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.