Tableau de requêtes JSON PostgreSQL contre plusieurs valeurs

17

Je veux écrire une requête contre le jsonbtype dans Postgres qui, étant donné un tableau d'ID clients, trouvera les groupes correspondants.

Étant donné cet exemple de tableau:

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"}]}');

J'ai trouvé une question similaire ( PostgreSql JSONB SELECT contre plusieurs valeurs ) et j'ai réussi à obtenir ce que je veux sur un tableau simple à l'aide de cette requête:

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

Cependant, je ne peux pas le faire fonctionner lorsque le tableau contient des objets JSON :

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

Voici ce que j'attends de ma requête:

grp "First" -> client "1"

groupe "Troisième" -> client "5"

BartZ
la source

Réponses:

16

Il y a un moyen: combiner l' opérateur de confinement@> avec la ANYconstruction :

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

Ou:

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

Il est essentiel de convertir jsonb[]explicitement le tableau . Et notez que chaque élément est un tableau JSON à l' intérieur comme l' @>exige l'opérateur . C'est donc un tableau de tableaux JSON.

Vous pouvez utiliser un index pour cela:

Le manuel indique explicitement que l'opérateur ?|est uniquement destiné aux chaînes .

Erwin Brandstetter
la source