MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Consultando dentro de arrays JSON do Postgres


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.