A resposta original a seguir se aplica apenas ao Postgres 9.3. Para uma resposta do Postgres 9.4, veja a atualização abaixo.
Isso se baseia nas respostas referenciadas de Erwin , mas é um pouco mais explícito para esta questão.
Os IDs neste caso são
bigint
s, então crie uma função auxiliar para converter um array JSON em um Postgres bigint
variedade: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;
Poderíamos ter facilmente (e talvez mais reutilizável) retornado um
text
array aqui em vez disso. Suspeito de indexação em bigint
é muito mais rápido que text
mas estou tendo dificuldade em encontrar evidências on-line para apoiar isso. Para construir o índice:
CREATE INDEX "myindex" ON "mytable"
USING GIN (json_array_bigint("blob"->'ids'));
Para consultar, isso funciona e usa o índice:
SELECT * FROM "mytable"
WHERE '{185603363289694211}' <@ json_array_bigint("blob"->'ids');
Fazer isso também funcionará para consulta, mas não usará o índice:
SELECT * FROM "mytable"
WHERE 185603363289694211 = ANY(json_array_bigint("blob"->'ids'));
Atualização para 9.4
O Postgres 9.4 introduziu o
jsonb
modelo. Esta é uma boa resposta SO sobre jsonb e quando você deve usá-lo sobre json
. Em resumo, se você estiver consultando o JSON, use jsonb
. Se você construir sua coluna como
jsonb
, você pode usar esta consulta:SELECT * FROM "mytable"
WHERE blob @> '{"ids": [185603363289694211]}';
O
@>
é o operador contém do Postgres, documentado para jsonb
aqui
.Graças à resposta de Alain
por trazer isso à minha atenção.