Comment créer un index sur un champ JSON dans Postgres?

111

Dans PostgreSQL 9.3 Beta 2 (?), Comment créer un index sur un champ JSON? Je l'ai essayé en utilisant l' ->opérateur utilisé pour hstoremais j'ai obtenu l'erreur suivante:

 CREATE TABLE publishers(id INT, info JSON);
 CREATE INDEX ON publishers((info->'name'));

ERREUR: le type de données json n'a pas de classe d'opérateur par défaut pour la méthode d'accès "btree" CONSEIL: Vous devez spécifier une classe d'opérateur pour l'index ou définir une classe d'opérateur par défaut pour le type de données.

rlib
la source
8
"Où est la question?" - DANS le titre
rlib
2
À l'avenir, veuillez consulter stackoverflow.com/tags/postgresql/info , la section «poser de meilleures questions»; cela pourrait aider à obtenir de meilleures réponses plus tôt avec moins de questions ennuyeuses.
Craig Ringer

Réponses:

186

A trouvé:

CREATE TABLE publishers(id INT, info JSON); 
CREATE INDEX ON publishers((info->>'name'));

Comme indiqué dans les commentaires, la différence subtile ici est ->>au lieu de ->. Le premier renvoie la valeur sous forme de texte, le second sous forme d'objet JSON.

rlib
la source
39
Juste au cas où vous cherchez la différence: c'est ->>au lieu de ->. Le premier renvoie la valeur sous forme de texte, le second renvoie un objet JSON.
Daniel Rikowski
35
Les doubles parenthèses sont également importantes.
Ron
11
@Jac_opo Il les extrait commeTEXT , cependant. Si vous voulez faire des comparaisons d'entiers au lieu de comparaisons de chaînes, vous devez ajouter un casting: ((info->>'name')::INT).
jpmc26
13
Si vous souhaitez créer un index sur un champ à l'intérieur d'un sous-objet de votre colonne JSON, grâce à @DanielRikowski, j'ai compris que je devais le faire create index idx_name on table_name ((json_column->'child_obj'->>'child_obj_field'));Nous devons d'abord utiliser ->pour obtenir l'objet JSON, puis ->>pour obtenir la valeur de l'objet enfant comme texte.
Corey Cole