Risposta breve
Puoi usare la funzione jsonb_array_elements()
in un join laterale e usa il suo risultato value
in espressioni complesse nel WHERE
clausola:
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('b', 'd')
AND value->>'label1' IN ('2', '3')
Distinto
La query può restituire righe duplicate quando le condizioni di filtro sono soddisfatte in più di un elemento dell'array in una singola riga, ad es.
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)
Quindi può essere ragionevole usare DISTINCT
nel SELECT
elenco:
SELECT DISTINCT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
o EXISTS
nel WHERE
clausola, che potrebbe essere un po' più veloce:
SELECT t.*
FROM test t
WHERE EXISTS (
SELECT
FROM jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
)
Puoi anche selezionare elementi dell'array corrispondenti nei casi in cui queste informazioni sono necessarie:
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)
Prestazioni
Il jsonb_array_elements()
la funzione è costosa. Per le tabelle più grandi l'uso della funzione può essere discutibile a causa del pesante carico del server e del lungo tempo di esecuzione di una query.
Mentre un indice GIN può essere utilizzato per query con @>
operatore:
CREATE INDEX ON test USING GIN (test_content)
nel caso della funzione ciò non è possibile. Le query supportate dall'indice possono essere fino a diverse decine di volte più veloci di quelle che utilizzano la funzione.