it-swarm.com.de

Überprüfen Sie, ob ein JSON-Array in MySQL ein Objekt enthält, dessen Schlüssel ein bestimmtes Datum enthält

ich versuche herauszufinden, ob es eine Zeile gibt, die ein bestimmtes Datum in einem JSON-Array enthält

Angenommen, meine Daten sehen folgendermaßen aus:

Tabellenanwendungen:

id | application_id | data
# Rows
1 | 1 | [{"data" : ["some", "data#1"], "date": "2016-04-21"}, {"data" : ["other", "data#1"], "date" : "2016-04-22"}]
2 | 2 | [{"data" : ["some", "data#2"], "date": "2016-04-21"}, {"data" : ["other", "data#2"], "date" : "2016-04-26"}]
3 | 1 | [{"data" : ["some", "data#3"], "date": "2016-04-22"}, {"data" : ["other", "data#3"], "date" : "2016-04-26"}]
4 | 3 | [{"data" : ["some", "data#4"], "date": "2016-04-26"}]

Wie finde ich alle Anwendungen, deren Daten das Datum '2016-04-26' Enthalten?

Im Grunde kann ich das also tun:

select id, json_extract(`data`, "$[*].date") from applications

Welches kehrt zurück:

1 | ["2016-04-21", "2016-04-22"]
2 | ["2016-04-21", "2016-04-26"]
3 | ["2016-04-22", "2016-04-26"]
4 | ["2016-04-26"]

Aber wenn ich versuche, json_extract In der WHERE -Klausel zu verwenden, kann ich es nur verwenden, wenn ich den Schlüssel des Arrays im Pfadargument von json_extract Explizit wie folgt sage:

select * from applications where json_extract(`data`, "$[0].date") = "2016-04-26"

dies gibt die Zeile mit der ID 4 korrekt zurück.

Wenn ich jedoch versuche, einen Platzhalter im Pfad zu verwenden, funktioniert dies nicht mehr:

select * from applications where json_extract(`data`, "$[*].date") = "2016-04-26"

dies sollte die Zeilen 2, 3, 4 zurückgeben.

Ich habe viele andere Optionen/Variationen ausprobiert, aber ich kann anscheinend keine Möglichkeit finden, die Abfrage korrekt zu strukturieren.

Ist so etwas mit der aktuellen Implementierung von MySQL JSON überhaupt möglich?

18
Klemen

Eine Lösung von Morgan Tucker - @morgo ist die Verwendung von json_contains wie so:

select * from applications where json_contains(`data`, '{"date" : "2016-04-26"}')

Im Moment ist die Antwort in Ordnung, aber ich glaube, dass es einige Leistungsprobleme geben kann und sich für mich etwas hackig anfühlt (siehe nächste Abfrage) - aber ich werde mich darum kümmern, wenn ich dort bin :)

Wenn ich einen Datumsbereich abfragen müsste (von 2016-04-24 bis 2016-04-26) Ich müsste ein einzelnes hinzufügen json_contains für jeden Tag in der Zeitspanne wie folgt:

select * from applications where json_contains(`data`, '{"date" : "2016-04-26"}') or json_contains(`data`, '{"date" : "2016-04-25"}') or json_contains(`data`, '{"date" : "2016-04-24"}')

Und dies würde ungültige Daten zurückgeben, wenn ich einen date Schlüssel hätte, der woanders verschachtelt ist

Wenn Sie also eine andere Lösung haben, würde ich gerne wissen

15
Klemen