Kurze Antwort
Sie können die Funktion jsonb_array_elements()
verwenden in einem lateralen Join und verwenden Sie dessen Ergebnis value
in komplexen Ausdrücken im WHERE
Klausel:
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('b', 'd')
AND value->>'label1' IN ('2', '3')
Eindeutig
Die Abfrage kann doppelte Zeilen zurückgeben, wenn die Filterbedingungen in mehr als einem Element des Arrays in einer einzelnen Zeile erfüllt sind, z. B.
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
id | test_content
--------------------------------------+----------------------------------------------------------------
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
(2 rows)
Daher kann es sinnvoll sein, DISTINCT
zu verwenden im SELECT
Liste:
SELECT DISTINCT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
oder EXISTS
im WHERE
-Klausel, die etwas schneller sein kann:
SELECT t.*
FROM test t
WHERE EXISTS (
SELECT
FROM jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
)
Sie können auch passende Array-Elemente auswählen, falls diese Informationen benötigt werden:
SELECT id, value
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
id | value
--------------------------------------+-------------------------------
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "a", "label1": "1"}
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "b", "label1": "2"}
(2 rows)
Leistung
Die jsonb_array_elements()
Funktion ist teuer. Bei größeren Tabellen kann die Nutzung der Funktion aufgrund der hohen Serverlast und der langen Ausführungszeit einer Abfrage fragwürdig sein.
Während ein GIN-Index für Abfragen mit @>
verwendet werden kann Betreiber:
CREATE INDEX ON test USING GIN (test_content)
bei der Funktion ist dies nicht möglich. Vom Index unterstützte Abfragen können bis zu mehrere Dutzend Mal schneller sein als solche, die die Funktion verwenden.