sql >> Base de Datos >  >> NoSQL >> MongoDB

Consulta dentro de matrices JSON de Postgres

La siguiente respuesta original solo se aplica a Postgres 9.3. Para obtener una respuesta de Postgres 9.4, consulte la Actualización a continuación.

Esto se basa en las respuestas de referencia de Erwin , pero es un poco más explícito para esta pregunta.

Los ID en este caso son bigint s, así que cree una función auxiliar para convertir una matriz JSON en un bigint de Postgres matriz:

CREATE OR REPLACE FUNCTION json_array_bigint(_j json)
  RETURNS bigint[] AS
$$
SELECT array_agg(elem::text::bigint)
FROM json_array_elements(_j) AS elem
$$
  LANGUAGE sql IMMUTABLE;

Podríamos haber devuelto fácilmente (y quizás de forma más reutilizable) un text matriz aquí en su lugar. Sospecho que está indexando en bigint es mucho más rápido que text pero estoy teniendo dificultades para encontrar evidencia en línea que respalde eso.

Para construir el índice:

CREATE INDEX "myindex" ON "mytable" 
  USING GIN (json_array_bigint("blob"->'ids'));

Para consultar, esto funciona y usa el índice:

SELECT * FROM "mytable" 
  WHERE '{185603363289694211}' <@ json_array_bigint("blob"->'ids');

Hacer esto también funcionará para realizar consultas, pero no usa el índice:

SELECT * FROM "mytable" 
  WHERE 185603363289694211 = ANY(json_array_bigint("blob"->'ids'));

Actualización para 9.4

Postgres 9.4 introdujo el jsonb escribe. Esta es una buena respuesta SO sobre jsonb y cuándo debería usarlo sobre json . En resumen, si alguna vez consulta el JSON, debe usar jsonb .

Si crea su columna como jsonb , puede utilizar esta consulta:

SELECT * FROM "mytable"
  WHERE blob @> '{"ids": [185603363289694211]}';

El @> es el operador de contenido de Postgres, documentado para jsonb aquí Gracias a la respuesta de Alain por traer esto a mi atención.