MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Interroger à l'intérieur des tableaux Postgres JSON

La réponse originale suivante s'applique uniquement à Postgres 9.3. Pour une réponse Postgres 9.4, voir la mise à jour ci-dessous.

Cela s'appuie sur les réponses référencées d'Erwin , mais est un peu plus explicite à cette question.

Les identifiants dans ce cas sont bigint s, créez donc une fonction d'assistance pour convertir un tableau JSON en un Postgres bigint tableau :

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;

Nous aurions pu facilement (et peut-être de manière plus réutilisable) renvoyer un text tableau ici à la place. Je soupçonne l'indexation sur bigint est beaucoup plus rapide que text mais j'ai du mal à trouver des preuves en ligne pour étayer cela.

Pour construire l'index :

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

Pour l'interrogation, cela fonctionne et utilise l'index :

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

Cela fonctionnera également pour les requêtes, mais cela n'utilisera pas l'index :

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

Mise à jour pour 9.4

Postgres 9.4 a introduit le jsonb taper. C'est une bonne réponse SO à propos de jsonb et quand l'utiliser sur json . En bref, si jamais vous interrogez le JSON, vous devez utiliser jsonb .

Si vous créez votre colonne en tant que jsonb , vous pouvez utiliser cette requête :

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

Le @> est l'opérateur contient de Postgres, documenté pour jsonb ici .Merci à la réponse d'Alain d'avoir porté cela à mon attention.