Wie suche ich JSON-Daten in MySQL?


74

Ich füge meine Daten in eine Datenbank mit ein json_encoded. Jetzt möchte ich in "Feature" suchen, kann es aber nicht.

MySQL-Abfrage:

SELECT  `id` ,  `attribs_json` 
FROM  `products` 
WHERE  `attribs_json` REGEXP  '"1":{"value":[^"3"$]'

Diese Abfrage zeigt mir alle Zeilen mit dem Schlüssel "1" und Wert ist alles, was nicht Wert ist "3".

Meine Daten sind:

{"feature":{"1":{"value":"["2","3"]"},
            "2":{"value":["1"]},
            "5":{"value":""},
            "3":{"value":["1"]},
            "9":{"value":""},
            "4":{"value":"\u0633\u0627\u062a\u0646"},
            "6":{"value":""},
            "7":{"value":""},
            "8":{"value":""}
           },
"show_counter":"0",
"show_counter_discount":""
}}

Ich möchte mir allen zeigen, dass der Schlüssel "1" und "3" einer der Werte ist
reza

Erklären Sie "kann nicht"! Welche Ausgabe erhalten Sie?
Ajoy

Ich möchte allen Produkten zeigen, dass die ID des Features 1 ist und einer der Werte des Features 3 ist. Das Feature ist ein Array wie dieses: Feature = Array (1 => Array (1,2,3), 2 => Array (1,4,7) )) Ich benutze Jsonencode, um es in der Datenbank zu speichern
Reza

Das klingt nach einer schrecklichen Idee. Sie würden davon profitieren, wenn Sie die Daten, die Sie filtern möchten, in ihre eigenen Spalten aufteilen und dann einfach das JSON-Material für zusätzliche Informationen verwenden, nach denen Sie nicht filtern.
Diggersworld

warum schreckliche Idee. Was sind die Nachteile davon?
Reza

Antworten:


133

Wenn Sie eine MySQL-Version> = 5.7 haben , können Sie Folgendes versuchen:

SELECT JSON_EXTRACT(name, "$.id") AS name
FROM table
WHERE JSON_EXTRACT(name, "$.id") > 3

Ausgabe:

+-------------------------------+
| name                          | 
+-------------------------------+
| {"id": "4", "name": "Betty"}  | 
+-------------------------------+


Weitere Informationen finden Sie im MySQL-Referenzhandbuch:
https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html


2
Wichtiger Hinweis: json_encodeSpeichert Integerst als doppelt quoierte Werte (also - stringTyp). Wenn auf der Suche nach gleich, JSON_EXTRACT(name, "$.id") = "4"muss anstelle vonJSON_EXTRACT(name, "$.id") = 4
Arnis Juraga

9
> In MySQL 5.7.9 und höher dient der Operator -> als Alias ​​für die Funktion JSON_EXTRACT (), wenn er mit zwei Argumenten verwendet wird. Ihr Beispiel lautet dann: SELECT name->"$.id" as name FROM table WHERE name->"$.id" > 3 Ich persönlich finde es einfacher, dem zu folgen.
Robin van Baalen

24

Wenn Sie MySQL verwenden, kann die neueste Version dazu beitragen, Ihre Anforderungen zu erfüllen.

select * from products where attribs_json->"$.feature.value[*]" in (1,3)

5
Was meinst du mit der neuesten Version von MySQL? In welcher Version wird es unterstützt?
Sérgio

In welcher Version wird der IN-Operator unterstützt?
Sérgio

2
MySQL 5.5 und höher @ Sérgio
Vishnu Prasanth G

1
mysql --version mysql Ver 14.14 Distrib 5.7.18, für Linux (x86_64) Warnung: (1235, "Diese Version von MySQL unterstützt noch keinen 'Vergleich von JSON im IN-Operator'")
Sérgio

12
  1. Das Speichern von JSON in einer Datenbank verletzt die erste normale Form.

    Das Beste, was Sie tun können, ist, Features zu normalisieren und in einer anderen Tabelle zu speichern. Dann können Sie eine viel besser aussehende und leistungsfähigere Abfrage mit Joins verwenden. Ihr JSON ähnelt sogar der Tabelle.

  2. MySQL 5.7 verfügt über eine integrierte JSON-Funktionalität:
    http://mysqlserverteam.com/mysql-5-7-lab-release-json-functions-part-2-querying-json-data/

  3. Das richtige Muster ist:

    WHERE  `attribs_json` REGEXP '"1":{"value":[^}]*"3"[^}]*}'
    

    [^}] wird mit jedem Zeichen außer übereinstimmen }


2
Einverstanden mit Nummer 1 oben, aber manchmal haben Sie einen Fall, in dem nur wenige Feldnamen in einer Tabelle zur Entwurfszeit unbekannt sind. Dies ist ein Fall, in dem Sie relationalen und nosql-Datenspeicher mischen können, indem Sie einen JSON-Datentyp in der Tabelle haben.
chrisl08

11

Ich benutze diese Abfrage

SELECT id FROM table_name WHERE field_name REGEXP '"key_name":"([^"])key_word([^"])"';
or
SELECT id FROM table_name WHERE field_name RLIKE '"key_name":"[[:<:]]key_word[[:>:]]"';

Die erste Abfrage verwende ich, um Teilwerte zu suchen. Die zweite Abfrage verwende ich, um das genaue Wort zu suchen.


MySQL 5.7 hat endlich JSON-Unterstützung. Es wird jedoch eine Weile dauern, bis dieses Update zum Mainstream wird. Als Kurzreferenz ist dies jedoch eine einfache Möglichkeit, einige Informationen zu extrahieren. Vielen Dank!
Tmarois

Es funktioniert nicht bei mir. Ich habe Struktur wie {"images":"-"}und SELECT id FROM parsed_redfin WHERE Daten "RLIKE" "Bilder": "[[: <:]] - [[:>:]]"; `gibt nichts zurück
Volatil3

-1

Ich denke...

Teilwert suchen:

SELECT id FROM table_name WHERE field_name REGEXP '"key_name":"([^"])*key_word([^"])*"';

Suche genaues Wort:

SELECT id FROM table_name WHERE field_name RLIKE '"key_name":"[[:<:]]key_word[[:>:]]"';

1
Dies ist genau das Gleiche wie eine der bereits vorhandenen Antworten. Es ist nicht nötig zu wiederholen, was Valentino gesagt hat :)
MBorg

-7

für MySQL alle (und 5.7)

SELECT LOWER(TRIM(BOTH 0x22 FROM TRIM(BOTH 0x20 FROM SUBSTRING(SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"'),LOCATE(0x2C,SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"')+1,LENGTH(json_filed)))),LOCATE(0x22,SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"'),LOCATE(0x2C,SUBSTRING(json_filed,LOCATE('\"ArrayItem\"',json_filed)+LENGTH('\"ArrayItem\"')+1,LENGTH(json_filed))))),LENGTH(json_filed))))) AS result FROM `table`;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.