MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Interrogazione all'interno degli array JSON di Postgres

La seguente risposta originale si applica solo a Postgres 9.3. Per una risposta Postgres 9.4, vedere l'aggiornamento di seguito.

Questo si basa su risposte referenziate di Erwin , ma è un po' più esplicito a questa domanda.

Gli ID in questo caso sono bigint s, quindi crea una funzione di supporto per convertire un array JSON in un Postgres bigint matrice:

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;

Avremmo potuto semplicemente (e forse in modo più riutilizzabile) restituire un text array qui invece. Sospetto che l'indicizzazione su bigint è molto più veloce di text ma ho difficoltà a trovare prove online a sostegno di ciò.

Per costruire l'indice:

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

Per la query, funziona e utilizza l'indice:

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

In questo modo funzionerà anche per le query, ma non utilizza l'indice:

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

Aggiornamento per 9.4

Postgres 9.4 ha introdotto il jsonb genere. Questa è una buona risposta SO su jsonb e quando dovresti usarlo su json . In breve, se stai interrogando il JSON, dovresti usare jsonb .

Se crei la tua colonna come jsonb , puoi utilizzare questa query:

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

Il @> is Postgres' contiene l'operatore, documentato per jsonb qui .Grazie alla risposta di Alain per averlo portato alla mia attenzione.