Conjunto de consultas JSON de PostgreSQL contra múltiples valores


17

Quiero escribir una consulta contra el jsonbtipo en Postgres que, dado un conjunto de ID de clientes, encontrará los grupos correspondientes.

Dada esta tabla de ejemplo:

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

Encontré una pregunta similar ( PostgreSql JSONB SELECT contra múltiples valores ) y logré lograr lo que quiero en una matriz simple usando esta consulta:

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

Sin embargo, no puedo hacer que funcione cuando la matriz contiene objetos JSON :

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

Esto es lo que espero de mi consulta:

grp "Primero" -> cliente "1"

grp "Tercero" -> cliente "5"

Respuestas:


16

Hay una manera: combinar el operador de contención@> con la ANYconstrucción :

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

O:

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

Es esencial emitir la matriz jsonb[]explícitamente. Y tenga en cuenta que cada elemento es una matriz JSON en el interior como lo @>requiere el operador . Entonces es una matriz de matrices JSON.

Puede usar un índice para esto:

El manual establece explícitamente que el operador ?|es solo para cadenas .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.