Het volgende originele antwoord is alleen van toepassing op Postgres 9.3. Zie de update hieronder voor een antwoord op Postgres 9.4.
Dit bouwt voort op Erwins gerefereerde antwoorden , maar is iets explicieter op deze vraag.
De ID's zijn in dit geval bigint
s, dus maak een hulpfunctie voor het converteren van een JSON-array naar een Postgres bigint
reeks:
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;
We hadden eenvoudig (en misschien beter herbruikbaar) een text
kunnen retourneren array hier in plaats daarvan. Ik vermoed indexering op bigint
is een stuk sneller dan text
maar ik vind het moeilijk om online bewijs te vinden om dat te staven.
Voor het bouwen van de index:
CREATE INDEX "myindex" ON "mytable"
USING GIN (json_array_bigint("blob"->'ids'));
Voor query's werkt dit en gebruikt de index:
SELECT * FROM "mytable"
WHERE '{185603363289694211}' <@ json_array_bigint("blob"->'ids');
Als u dit doet, werkt dit ook voor query's, maar het maakt geen gebruik van de index:
SELECT * FROM "mytable"
WHERE 185603363289694211 = ANY(json_array_bigint("blob"->'ids'));
Update voor 9,4
Postgres 9.4 introduceerde de jsonb
type. Dit is een goed SO-antwoord over jsonb
en wanneer je het moet gebruiken over json
. Kortom, als u ooit de JSON opvraagt, moet u jsonb
. gebruiken .
Als u uw kolom opbouwt als jsonb
, kunt u deze zoekopdracht gebruiken:
SELECT * FROM "mytable"
WHERE blob @> '{"ids": [185603363289694211]}';
De @>
is Postgres' bevat operator, gedocumenteerd voor jsonb
hier
.Dankzij Alain's antwoord
om dit onder mijn aandacht te brengen.