Krótka odpowiedź
Możesz użyć funkcji jsonb_array_elements()
w złączeniu bocznym i użyj jego wyniku value
w wyrażeniach złożonych w WHERE
klauzula:
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('b', 'd')
AND value->>'label1' IN ('2', '3')
Wyraźne
Zapytanie może zwrócić zduplikowane wiersze, gdy warunki filtrowania są spełnione w więcej niż jednym elemencie tablicy w jednym wierszu, np.
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)
Dlatego rozsądne może być użycie DISTINCT
w SELECT
lista:
SELECT DISTINCT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
lub EXISTS
w WHERE
klauzula, która może być nieco szybsza:
SELECT t.*
FROM test t
WHERE EXISTS (
SELECT
FROM jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
)
Możesz także wybrać pasujące elementy tablicy w przypadkach, gdy ta informacja jest potrzebna:
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)
Wydajność
jsonb_array_elements()
funkcja jest droga. W przypadku większych tabel użycie funkcji może być wątpliwe ze względu na duże obciążenie serwera i długi czas wykonania zapytania.
Podczas gdy indeks GIN może być używany do zapytań z @>
operator:
CREATE INDEX ON test USING GIN (test_content)
w przypadku funkcji nie jest to możliwe. Zapytania obsługiwane przez indeks mogą być nawet kilkadziesiąt razy szybsze niż te korzystające z funkcji.