2016-05-09 3 views
1

Ich versuche, alle Rezepte in einer bestimmten Kategorie zu finden, wo die Schlüssel/Wert-Daten in einer PostgreSQL-Jsonb-Spalte aufgezeichnet werden (und der Wert wird als Array gespeichert).Wie kann ich mithilfe von jsonb (PostgreSQL) Elemente mit einem bestimmten Wert abrufen, die als Array gespeichert sind?

Zum Beispiel sage ich „Daten“, wie meine jsonb Spalte in der „Rezepte“ Tisch haben, und ich habe drei Einträge wie folgt:

"Recipe 1" contains a "data" with key/value of: "category_ids"=>[123, 4059] 
"Recipe 2" contains a "data" with key/value of: "category_ids"=>[405, 543] 
"Recipe 3" contains a "data" with key/value of: "category_ids"=>[567, 982] 

ich nur Elemente abrufen möchten, dass die „405 enthalten "Kategorie-ID-Wert (dh nur Rezept 2 oben)

Dies ist, was ich habe auf Rails so Ruby-weit mit der PostgreSQL-Datenbank abzufragen:

Recipe.where("(data ->> 'category_ids') LIKE '%405%'") 

jedoch, dass beide abruft‚Rezept 1‘ und "Rezept 2", weil beide Text "405" enthalten.

Welche Abfrage sollte ich verwenden, um Rezepte nur mit der ID "405" korrekt abzurufen?

Antwort

1

Sie können auch mit json_array_elements verwenden IN direkt an:

Recipe.where("'405' IN (SELECT json_array_elements(data->'category_ids')::text)") 

Und wenn Ihre Spalte eine jsonb Spalte ist, können Sie in ähnlicher Weise tun:

Recipe.where("'405' IN (SELECT jsonb_array_elements(data->'category_ids')::text)") 
+0

Danke, Ziggy bekam ich diese Fehlermeldung: Active :: StatementInvalid: PG :: UndefinedFunction: eRROR: function json_array_elements (jsonb) nicht Meine postgresql Version existiert ist 9.5 (mit Rails Version 4.2.6). Weißt du, ob ich diese Funktion in psql aktivieren muss? – sjsc

+1

Ich denke, ich weiß jetzt :) Ich tat dies und es funktioniert: Recipe.where ('' 405 'IN (SELECT jsonb_array_elements (data -> 'category_ids') :: text) ") Also anstelle von "json_array_elements" habe ich "jsonb_array_elements" wegen der jsonb-Spalte verwendet. Vielen Dank !! – sjsc

1

Sie benötigen ANY Funktion. So etwas wie

select * from t where '405' = any (
    ARRAY(
    SELECT e::text FROM json_array_elements(data->'category_ids') e 
) 
); 

oder

select * from t where '405' = any (
    ARRAY(
    SELECT e::text FROM jsonb_array_elements(data->'category_ids') e 
) 
); 

, wenn Ihr Typ ist jsonb (höher als 9,3 Postgres Version)

http://sqlfiddle.com/#!15/1a895/1

+0

Vielen Dank cur4so :) Ich verstehe PostgreSQL nicht zu viel, so habe ich Ziggys Lösung oben, dass die Art und Weise Rails enthält, es zu tun . Die jsonb_array_elements (Daten -> 'category_ids') ist der Schlüssel, also vielen Dank. Dies war die Abfrage-Ausgabe, die für mich funktionierte, nachdem Sie den Rails-Befehl ausgeführt haben, der Ihrem sehr ähnlich ist: SELECT \ "Rezepte \". * FROM \ "recipes \" WHERE ('405' IN (SELECT jsonb_array_elements (. Daten -> 'Category_ids') :: text))“ – sjsc

Verwandte Themen