PostgreSQL JSON масив запитів проти кількох значень


18

Я хочу написати запит проти jsonbтипу в Postgres, який, маючи масив ідентифікаторів клієнтів, знайде відповідні групи.

Враховуючи цей приклад таблиці:

CREATE TABLE grp(d JSONB NOT NULL);

INSERT INTO grp VALUES
   ('{"name":"First","arr":["foo"], "customers":[{"id":"1", "name":"one"},{"id":"2", "name":"two"}]}')
 , ('{"name":"Second","arr":["foo","bar"], "customers":[{"id":"3", "name":"three"},{"id":"4", "name":"four"}]}')
 , ('{"name":"Third","arr":["bar","baz"], "customers":[{"id":"5", "name":"five"},{"id":"6", "name":"seven"}]}');

Я знайшов подібне запитання ( PostgreSql JSONB SELECT проти декількох значень ) і зумів досягти того, що я хочу на простому масиві, використовуючи цей запит:

SELECT d FROM grp WHERE d->'arr' ?| ARRAY['foo', 'bar'];

Однак я не можу змусити його працювати, коли масив містить об'єкти JSON :

SELECT d FROM grp WHERE d->'customers' ?| ARRAY['{"id":"1"}', '{"id":"5"}'];

Ось що я очікую від свого запиту:

grp "Перший" -> клієнт "1"

grp "Третій" -> клієнт "5"

Відповіді:


17

Є спосіб: поєднати оператор стримування@> з ANYконструкцією :

SELECT d
FROM   grp
WHERE  d->'customers' @> ANY (ARRAY ['[{"id":"1"}]', '[{"id":"5"}]']::jsonb[]);

Або:

...
WHERE d->'customers' @> ANY ('{"[{\"id\": \"1\"}]","[{\"id\": \"5\"}]"}'::jsonb[]);

Важливо передати масив jsonb[]явно. І зауважте, що кожен елемент - це масив JSON всередині, як @>вимагає оператор . Отже, це масив масивів JSON.

Ви можете використовувати індекс для цього:

У посібнику прямо вказано, що оператор ?|призначений лише для рядків .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.