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":""
}}
reza
quelle
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

Sachin Vairagi
quelle
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)
Vishnu Prasanth G.
quelle
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 }

Naktibalda
quelle
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.

Valentino
quelle
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[[:>:]]"';
romantisches zang
quelle
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`;
0x00
quelle