PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 17.6 » Langage SQL » Fonctions et opérateurs » Fonctions et opérateurs JSON

9.16. Fonctions et opĂ©rateurs JSON #

Cette section dĂ©crit :

  • les fonctions et opĂ©rateurs pour traiter et crĂ©er des donnĂ©es JSON

  • le langage de chemin SQL/JSON

  • les fonctions de requĂȘtage SQL/JSON

Pour fournir un support natif des types de données JSON dans un environnement SQL, PostgreSQL implémente le modÚle de données SQL/JSON. Ce modÚle comprend des séquences d'éléments. Chaque élément peut contenir des valeurs SQL scalaires, avec une valeur null SQL/JSON supplémentaire, et des structures de données composites qui utilisent les tableaux et objets JSON. Le modÚle est une formalisation du modÚle de données compris dans la spécification JSON de la RFC 7159.

SQL/JSON vous permet de gĂ©rer des donnĂ©es JSON parmi les donnĂ©es SQL habituelles avec un support des transactions, incluant :

  • Le chargement de donnĂ©es JSON dans la base de donnĂ©es et son stockage dans des colonnes SQL standards, tout comme des chaĂźnes de caractĂšres ou des chaĂźnes binaires.

  • La gĂ©nĂ©ration d'objets JSON et de tableaux Ă  partir de donnĂ©es relationnelles.

  • Le requĂȘtage de donnĂ©es JSON en utilisant les fonctions de requĂȘtage SQL/JSON et les expressions du langage de chemin SQL/JSON.

Pour en savoir plus sur le standard SQL/JSON, voir [sqltr-19075-6]. Pour des dĂ©tails sur les types JSON supportĂ©s dans PostgreSQL, voir Section 8.14.

9.16.1. Traiter et crĂ©er des donnĂ©es JSON #

Tableau 9.45 affiche les opĂ©rateurs disponibles pour les types de donnĂ©es JSON (voir Section 8.14). De plus, les opĂ©rateurs de comparaison habituels indiquĂ©s dans Tableau 9.1 sont disponibles pour le type jsonb, mais pas pour le type json. Les opĂ©rateurs de comparaison suivent les rĂšgles de tri des opĂ©rateurs B-tree indiquĂ©s dans Section 8.14.4. Voir aussi Section 9.21 pour la fonction d'agrĂ©gat json_agg qui agrĂšge les valeurs d'enregistrements sous la forme d'un JSON, pour la fonction d'agrĂ©gat json_object_agg qui agrĂšge des paires de valeurs dans un objet JSON, et leurs Ă©quivalents jsonb, Ă  savoir jsonb_agg et jsonb_object_agg.

Tableau 9.45. OpĂ©rateurs json et jsonb

Opérateur

Description

Exemple(s)

json -> integer → json

jsonb -> integer → jsonb

Extrait le n-iÚme élément d'un tableau JSON (les éléments du tableau sont indexés à partir de zéro, mais les nombres négatifs sont pris en compte à partir de la fin).

'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> 2 → {"c":"baz"}

'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> -3 → {"a":"foo"}

json -> text → json

jsonb -> text → jsonb

Extrait le champ objet JSON avec la clé donnée.

'{"a": {"b":"foo"}}'::json -> 'a' → {"b":"foo"}

json ->> integer → text

jsonb ->> integer → text

Extrait le n-iÚme élément d'un tableau JSON, comme le text.

'[1,2,3]'::json ->> 2 → 3

json ->> text → text

jsonb ->> text → text

Extrait le champ objet JSON d'aprÚs la clé donnée, comme text.

'{"a":1,"b":2}'::json ->> 'b' → 2

json #> text[] → json

jsonb #> text[] → jsonb

Extrait le sous-objet JSON d'un chemin spĂ©cifiĂ©, oĂč les Ă©lĂ©ments du chemin peuvent ĂȘtre soit les clĂ©s d'un champ, soit les indices d'un tableau.

'{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}' → "bar"

json #>> text[] → text

jsonb #>> text[] → text

Extrait le sous-objet JSON au chemin spécifié avec text.

'{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}' → bar


Note

Les opĂ©rateurs d'extraction champ/Ă©lĂ©ment/chemin renvoient NULL, plutĂŽt qu'une erreur, si l'entrĂ©e JSON n'a pas la bonne structure correspondant Ă  la requĂȘte ; par exemple si la clĂ© ou l'Ă©lĂ©ment du tableau n'existe pas.

Quelques opĂ©rateurs supplĂ©mentaires existent seulement pour le type jsonb, comme indiquĂ© dans Tableau 9.46. Section 8.14.4 dĂ©crit comment ces opĂ©rateurs peuvent ĂȘtre utilisĂ©s pour rechercher efficacement les donnĂ©es jsonb indexĂ©es.

Tableau 9.46. OpĂ©rateurs jsonb supplĂ©mentaires

Opérateur

Description

Exemple(s)

jsonb @> jsonb → boolean

Est-ce que la premiĂšre valeur JSON contient la seconde ? (Voir Section 8.14.3 pour les dĂ©tails sur la notion de contenu.)

'{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb → t

jsonb <@ jsonb → boolean

Est-ce que la premiĂšre valeur JSON est contenue dans la seconde ?

'{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb → t

jsonb ? text → boolean

Est-ce que la chaĂźne de caractĂšres existe comme clĂ© de haut niveau ou Ă©lĂ©ment de tableau dans la valeur JSON ?

'{"a":1, "b":2}'::jsonb ? 'b' → t

'["a", "b", "c"]'::jsonb ? 'b' → t

jsonb ?| text[] → boolean

Est-ce qu'une des chaĂźnes du tableau de texte existe comme clĂ© de haut niveau ou comme Ă©lĂ©ment de tableau ?

'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] → t

jsonb ?& text[] → boolean

Est-ce que toutes les chaĂźnes du tableau de texte existent comme clĂ©s de haut niveau ou comme Ă©lĂ©ments de tableau ?

'["a", "b", "c"]'::jsonb ?& array['a', 'b'] → t

jsonb || jsonb → jsonb

ConcatĂšne deux valeurs jsonb. ConcatĂ©ner deux tableaux gĂ©nĂšre un tableau contenant tous les Ă©lĂ©ments de chaque entrĂ©e. ConcatĂ©ner deux objets gĂ©nĂšre un objet contenant l'union de leurs clĂ©s, en prenant la valeur du deuxiĂšme objet quand il existe deux clĂ©s dupliquĂ©es. Tous les autres cas sont traitĂ©s en convertissant une entrĂ©e non tableau en un tableau Ă  un seul Ă©lĂ©ment, puis en le traitant comme pour deux tableaux. N'est pas rĂ©cursif : seul le tableau ou la structure objet de haut niveau est assemblĂ©.

'["a", "b"]'::jsonb || '["a", "d"]'::jsonb → ["a", "b", "a", "d"]

'{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb → {"a": "b", "c": "d"}

'[1, 2]'::jsonb || '3'::jsonb → [1, 2, 3]

'{"a": "b"}'::jsonb || '42'::jsonb → [{"a": "b"}, 42]

Pour concaténer un tableau à un autre tableau dans une entrée unique, il faut l'envelopper dans une couche supplémentaire de tableau, par exemple :

'[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) → [1, 2, [3, 4]]

jsonb - text → jsonb

Supprime une clé (et sa valeur) à partir d'un objet JSON, ou les valeurs correspondantes de chaßnes à partir d'un tableau JSON.

'{"a": "b", "c": "d"}'::jsonb - 'a' → {"c": "d"}

'["a", "b", "c", "b"]'::jsonb - 'b' → ["a", "c"]

jsonb - text[] → jsonb

Supprime toutes les clés ou tous les éléments de tableau correspondant à partir de l'opérande gauche.

'{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[] → {}

jsonb - integer → jsonb

Supprime l'élément de tableau pour l'index spécifié (les nombres négatifs se décomptent à partir de la fin). Renvoie une erreur si la valeur JSON n'est pas un tableau.

'["a", "b"]'::jsonb - 1 → ["a"]

jsonb #- text[] → jsonb

Supprime le champ ou l'Ă©lĂ©ment de tableau sur le chemin indiquĂ©, les Ă©lĂ©ments du chemin pouvant ĂȘtre soit des clĂ©s de champ, soit des indices de tableau.

'["a", {"b":1}]'::jsonb #- '{1,b}' → ["a", {}]

jsonb @? jsonpath → boolean

Est-ce que le chemin JSON renvoie tout Ă©lĂ©ment pour la valeur JSON spĂ©cifiĂ©e ? (Ceci est utile seulement avec les expressions de chemin JSON du standard SQL, pas avec les expressions de vĂ©rification du prĂ©dicat, car ces derniĂšres renvoient toujours une valeur.)

'{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' → t

jsonb @@ jsonpath → boolean

Renvoie le résultat SQL booléen d'une vérification de prédicat du chemin JSON pour la valeur JSON indiquée. (Cela n'est utile qu'avec les expressions de vérification de prédicat, et non avec les expressions de chemin JSON du standard SQL, car il renverra NULL si le résultat du chemin n'est pas une seule valeur booléenne.)

'{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' → t


Note

Les opĂ©rateurs @? et @@ du type jsonpath suppriment les erreurs suivantes : champ objet ou Ă©lĂ©ment de tableau manquant, type d'Ă©lĂ©ment JSON inattendu, erreurs de date/heure ou de numĂ©rique. Les fonctions relatives Ă  jsonpath dĂ©crites ci-dessous peuvent aussi supprimer ce type d'erreurs Ă  la demande. Ce comportement pourrait ĂȘtre utile lors de la recherche de collections de documents JSON de diffĂ©rentes structures.

Tableau 9.47 montre les fonctions disponibles pour construire des valeurs json et jsonb. Certaines fonctions de cette table ont une clause RETURNING, qui indique le type de donnĂ©es renvoyĂ©es. Il doit ĂȘtre parmi json, jsonb, bytea, un type chaĂźne de caractĂšres (text, char, varchar ou nchar), ou un type qui peut ĂȘtre converti en json. Par dĂ©faut, le type json est renvoyĂ©.

Tableau 9.47. Fonctions de crĂ©ation de JSON

Fonction

Description

Exemple(s)

to_json ( anyelement ) → json

to_jsonb ( anyelement ) → jsonb

Convertit toute valeur SQL en json ou jsonb. Les tableaux et valeurs composites sont convertis rĂ©cursivement en tableaux et en objets (les tableaux multidimensionnels deviennent des tableaux de tableaux en JSON). Sinon, s'il existe une conversion entre le type de donnĂ©es SQL et json, la fonction de conversion sera utilisĂ©e pour rĂ©aliser la conversion ;[a] sinon, une valeur JSON scalaire est produite. Pour tout scalaire autre qu'un nombre, un boolĂ©en ou une valeur NULL, la reprĂ©sentation textuelle sera utilisĂ©e avec les Ă©chappements nĂ©cessaires pour la transformer en valeur JSON valide.

to_json('Fred said "Hi."'::text) → "Fred said \"Hi.\""

to_jsonb(row(42, 'Fred said "Hi."'::text)) → {"f1": 42, "f2": "Fred said \"Hi.\""}

array_to_json ( anyarray [, boolean ] ) → json

Convertit un tableau SQL en tableau JSON. Le comportement est le mĂȘme que to_json sauf que des sauts de ligne seront ajoutĂ©s entre les Ă©lĂ©ments de tableau de haut niveau si le paramĂštre boolĂ©en optionnel vaut true.

array_to_json('{{1,5},{99,100}}'::int[]) → [[1,5],[99,100]]

json_array ( [ { value_expression [ FORMAT JSON ] } [, ...] ] [ { NULL | ABSENT } ON NULL ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

json_array ( [ query_expression ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

Construit un tableau JSON Ă  partir d'une sĂ©rie de paramĂštres value_expression ou Ă  partir des rĂ©sultats de query_expression, qui doit ĂȘtre une requĂȘte SELECT renvoyant une seule colonne. Si ABSENT ON NULL est prĂ©cisĂ©, les valeurs NULL sont ignorĂ©es. C'est toujours le cas si une query_expression est utilisĂ©e.

json_array(1,true,json '{"a":null}') → [1, true, {"a":null}]

json_array(SELECT * FROM (VALUES(1),(2)) t) → [1, 2]

row_to_json ( record [, boolean ] ) → json

Convertit une valeur composite SQL en objet JSON. Le comportement est le mĂȘme que to_json sauf que des sauts de ligne seront ajoutĂ©s entre les Ă©lĂ©ments de tableau de haut niveau si le paramĂštre boolĂ©en optionnel vaut true.

row_to_json(row(1,'foo')) → {"f1":1,"f2":"foo"}

json_build_array ( VARIADIC "any" ) → json

jsonb_build_array ( VARIADIC "any" ) → jsonb

Construit un tableau JSON avec des types potentiellement hétérogÚnes à partir d'une liste d'arguments de longueur variable. Chaque argument est converti avec la fonction to_json ou to_jsonb.

json_build_array(1, 2, 'foo',4,5) → [1, 2, "foo", 4, 5]

json_build_object ( VARIADIC "any" ) → json

jsonb_build_object ( VARIADIC "any" ) → jsonb

Construit un objet JSON Ă  partir d'une liste d'arguments de longueur indĂ©finie. Par convention, la liste d'arguments consiste en des clĂ©s et valeurs en alternance. Les arguments clĂ©s sont convertis en texte ; les arguments valeurs sont convertis via les fonctions to_json ou to_jsonb.

json_build_object('foo', 1, 2, row(3, 'bar')) → {"foo" : 1, "2" : {"f1":3,"f2":"bar"}}

json_object ( [ { key_expression { VALUE | ':' } value_expression [ FORMAT JSON [ ENCODING UTF8 ] ] }[, ...] ] [ { NULL | ABSENT } ON NULL ] [ { WITH | WITHOUT } UNIQUE [ KEYS ] ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

Construit un objet avec toutes les paires clĂ©/valeur donnĂ©es ou un objet vide si aucune n'est donnĂ©e. key_expression est une expression scalaire dĂ©finissant la clĂ© JSON, qui est convertie dans le type text. Elle ne peut pas ĂȘtre NULL et elle ne peut pas appartenir Ă  un type qui a une conversion vers le type json. Si WITH UNIQUE KEYS est indiquĂ©, il ne doit pas y avoir de key_expression dupliquĂ©. Toute paire pour laquelle value_expression vaut NULL est omise de la sortie si ABSENT ON NULL est indiquĂ©e ; si NULL ON NULL est indiquĂ©e ou si la clause est est omise, la clĂ© est inclue avec la valeur NULL.

json_object('code' VALUE 'P123', 'title': 'Jaws') → {"code" : "P123", "title" : "Jaws"}

json_object ( text[] ) → json

jsonb_object ( text[] ) → jsonb

Construit un objet JSON à partir d'un tableau de texte. Le tableau doit avoir soit exactement une dimension avec un nombre pair de membres, auquel cas ils sont pris comme des paires alternantes clé/valeur, ou deux dimensions de telle façon que le tableau interne a exactement deux éléments, pris comme une paire clé/valeur. Toutes les valeurs sont converties en chaßne JSON.

json_object('{a, 1, b, "def", c, 3.5}') → {"a" : "1", "b" : "def", "c" : "3.5"}

json_object('{{a, 1}, {b, "def"}, {c, 3.5}}') → {"a" : "1", "b" : "def", "c" : "3.5"}

json_object ( keys text[], values text[] ) → json

jsonb_object ( keys text[], values text[] ) → jsonb

Cette forme de json_object prend les clés et valeurs à partir de tableaux de texte séparés. Pour le reste, elle est identique à la forme à un argument.

json_object('{a, b}', '{1,2}') → {"a": "1", "b": "2"}

json ( expression [ FORMAT JSON [ ENCODING UTF8 ]] [ { WITH | WITHOUT } UNIQUE [ KEYS ]] ) → json

Convertit une expression donnée spécifiée comme une chaßne text ou bytea (en encodage UTF8) en une valeur JSON. Si expression est NULL, une valeur NULL SQL est renvoyée. Si WITH UNIQUE est spécifié, l'expression ne doit pas contenir de doublon (clé d'objet).

json('{"a":123, "b":[true,"foo"], "a":"bar"}') → {"a":123, "b":[true,"foo"], "a":"bar"}

json_scalar ( expression )

Convertit une valeur scalaire SQL donnée en une valeur scalaire JSON. Si l'entrée est NULL, une valeur NULL SQL est renvoyée. Si l'entrée est un nombre ou une valeur booléenne, une valeur numérique ou booléenne correspondante en JSON est renvoyée. Pour toute autre valeur, une chaßne JSON est renvoyée.

json_scalar(123.45) → 123.45

json_scalar(CURRENT_TIMESTAMP) → "2022-05-10T10:51:04.62128-04:00"

json_serialize ( expression [ FORMAT JSON [ ENCODING UTF8 ] ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ] )

Convertit une expression SQL/JSON en une chaĂźne de caractĂšres ou en une chaĂźne binaire. L'expression peut ĂȘtre de n'importe quel type JSON, ou chaĂźne de caractĂšres, ou bytea en encodage UTF8. Le type renvoyĂ© utilisĂ© dans RETURNING peut ĂȘtre n'importe quel type de chaĂźne de caractĂšres ou bytea. Le type par dĂ©faut est text.

json_serialize('{ "a" : 1 } ' RETURNING bytea) → \x7b20226122203a2031207d20

[a] Par exemple, l'extension hstore contient une conversion de hstore vers json, pour que les valeurs hstore converties par les fonctions de création JSON soient représentées en tant qu'objets JSON, et non pas comme des valeurs de type chaßne de caractÚres.


Tableau 9.48 dĂ©taille les possibilitĂ©s de SQL/JSON pour tester du JSON.

Tableau 9.48. Fonctions de test SQL/JSON

Fonction

Description

Exemple(s)

expression IS [ NOT ] JSON [ { VALUE | SCALAR | ARRAY | OBJECT } ] [ { WITH | WITHOUT } UNIQUE [ KEYS ] ]

Ce prĂ©dicat teste si expression peut ĂȘtre analysĂ© comme du JSON, possiblement d'un type indiquĂ©. Si SCALAR, ARRAY ou OBJECT est prĂ©cisĂ©, le test revient Ă  savoir si le JSON est de ce type spĂ©cifique. Si WITH UNIQUE KEYS est prĂ©cisĂ©, alors tout objet dans l'expression est aussi testĂ© pour voir s'il contient des clĂ©s dupliquĂ©es.

SELECT js,
  js IS JSON "json?",
  js IS JSON SCALAR "scalar?",
  js IS JSON OBJECT "object?",
  js IS JSON ARRAY "array?"
FROM (VALUES
      ('123'), ('"abc"'), ('{"a": "b"}'), ('[1,2]'),('abc')) foo(js);
     js     | json? | scalar? | object? | array?
------------+-------+---------+---------+--------
 123        | t     | t       | f       | f
 "abc"      | t     | t       | f       | f
 {"a": "b"} | t     | f       | t       | f
 [1,2]      | t     | f       | f       | t
 abc        | f     | f       | f       | f

SELECT js,
  js IS JSON OBJECT "object?",
  js IS JSON ARRAY "array?",
  js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?",
  js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?"
FROM (VALUES ('[{"a":"1"},
 {"b":"2","b":"3"}]')) foo(js);
-[ RECORD 1 ]-+--------------------
js            | [{"a":"1"},        +
              |  {"b":"2","b":"3"}]
object?       | f
array?        | t
array w. UK?  | f
array w/o UK? | t


Tableau 9.49 montre les fonctions disponibles pour le traitement de valeurs json et jsonb.

Tableau 9.49. Fonctions de traitement JSON

Fonction

Description

Exemple(s)

json_array_elements ( json ) → setof json

jsonb_array_elements ( jsonb ) → setof jsonb

Étend le tableau JSON de haut niveau en un ensemble de valeurs JSON.

select * from json_array_elements('[1,true, [2,false]]') →

   value
-----------
 1
 true
 [2,false]
       

json_array_elements_text ( json ) → setof text

jsonb_array_elements_text ( jsonb ) → setof text

Étend le tableau JSON de haut niveau en un ensemble de valeurs de type text.

select * from json_array_elements_text('["foo", "bar"]') →

   value
-----------
 foo
 bar
       

json_array_length ( json ) → integer

jsonb_array_length ( jsonb ) → integer

Renvoie le nombre d'éléments dans le tableau JSON de haut niveau.

json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') → 5

jsonb_array_length('[]') → 0

json_each ( json ) → setof record ( key text, value json )

jsonb_each ( jsonb ) → setof record ( key text, value jsonb )

Étend l'objet JSON de haut niveau en un ensemble de paires clĂ©/valeur.

select * from json_each('{"a":"foo", "b":"bar"}') →

 key | value
-----+-------
 a   | "foo"
 b   | "bar"
       

json_each_text ( json ) → setof record ( key text, value text )

jsonb_each_text ( jsonb ) → setof record ( key text, value text )

Étend l'objet JSON de haut niveau en un ensemble de paires clĂ©/valeur. Les value renvoyĂ©es seront de type text.

select * from json_each_text('{"a":"foo", "b":"bar"}') →

 key | value
-----+-------
 a   | foo
 b   | bar
       

json_extract_path ( from_json json, VARIADIC path_elems text[] ) → json

jsonb_extract_path ( from_json jsonb, VARIADIC path_elems text[] ) → jsonb

Extrait un sous-objet JSON au chemin spĂ©cifiĂ©. (Ceci est fonctionnellement Ă©quivalent Ă  l'opĂ©rateur #>, mais Ă©crire le chemin sous la forme d'une liste peut ĂȘtre plus agrĂ©able dans certains cas.)

json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6') → "foo"

json_extract_path_text ( from_json json, VARIADIC path_elems text[] ) → text

jsonb_extract_path_text ( from_json jsonb, VARIADIC path_elems text[] ) → text

Extrait le sous-objet JSON au chemin spécifié sous la forme d'un text. (Ceci est équivalent fonctionnement à l'opérateur #>>.)

json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6') → foo

json_object_keys ( json ) → setof text

jsonb_object_keys ( jsonb ) → setof text

Renvoie l'ensemble de clés dans l'objet JSON de haut niveau.

select * from json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') →

 json_object_keys
------------------
 f1
 f2
       

json_populate_record ( base anyelement, from_json json ) → anyelement

jsonb_populate_record ( base anyelement, from_json jsonb ) → anyelement

Étend l'objet JSON de haut niveau en une ligne ayant le type composite de l'argument base. L'objet JSON est parcouru pour y trouver les champs dont le nom correspond aux noms de colonnes du type de la ligne en sortie, et leurs valeurs sont insĂ©rĂ©es dans ces colonnes en sortie. (Les champs qui ne correspondent Ă  aucun nom de colonne en sortie sont ignorĂ©s.) Dans le cas d'une utilisation typique, la valeur de base est simplement NULL, ce qui signifie que toute colonne en sortie qui ne correspond pas Ă  un champ d'objet sera remplie avec un NULL. NĂ©anmoins, si base ne vaut pas NULL, alors les valeurs qu'il contient seront utilisĂ©es pour les colonnes sans correspondance.

Pour convertir une valeur JSON au type SQL d'une colonne en sortie, les rĂšgles suivantes sont appliquĂ©es sur cette sĂ©quence :

  • Une valeur JSON null est convertie en NULL SQL dans tous les cas.

  • Si la colonne en sortie est de type json ou jsonb, la valeur JSON est reproduite exactement.

  • Si la colonne en sortie est un type (de ligne) composite, et que la valeur JSON est un objet JSON, les champs de l'objet sont convertis en colonnes du type de ligne par application rĂ©cursive de ces rĂšgles.

  • De la mĂȘme façon, si la colonne en sortie est un type tableau et que la valeur JSON est un tableau JSON, les Ă©lĂ©ments du tableau JSON sont convertis en Ă©lĂ©ments du tableau en sortie par application rĂ©cursive de ces rĂšgles.

  • Sinon, si la valeur JSON est une chaĂźne, le contenu de la chaĂźne est donnĂ© Ă  la fonction de conversion en entrĂ©e pour le type de donnĂ©es de la colonne.

  • Sinon, la reprĂ©sentation textuelle habituelle de la valeur JSON est envoyĂ©e Ă  la fonction de conversion en entrĂ©e pour le type de donnĂ©es de la colonne.

Bien que l'exemple ci-dessous utilise une valeur constante JSON, une utilisation typique serait de rĂ©fĂ©rencer une colonne json ou jsonb latĂ©ralement d'une autre table dans la clause FROM de la requĂȘte. Écrire json_populate_record dans la clause FROM est une bonne pratique, car toutes les colonnes extraites sont utilisables sans avoir Ă  faire des appels dupliquĂ©s Ă  la fonction.

create type subrowtype as (d int, e text); create type myrowtype as (a int, b text[], c subrowtype);

select * from json_populate_record(null::myrowtype, '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}, "x": "foo"}') →

 a |   b       |      c
---+-----------+-------------
 1 | {2,"a b"} | (4,"a b c")
       

jsonb_populate_record_valid ( base anyelement, from_json json ) → boolean

Fonction pour tester jsonb_populate_record. Renvoie true si l'entrĂ©e jsonb_populate_record se termine sans aucune erreur pour l'objet JSON donnĂ© ; c'est-Ă -dire, si l'entrĂ©e est valide, sinon false.

create type jsb_char2 as (a char(2));

select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aaa"}'); →

 jsonb_populate_record_valid
-----------------------------
 f
(1 row)

select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aaa"}') q; →

ERROR:  value too long for type character(2)

select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aa"}'); →

 jsonb_populate_record_valid
-----------------------------
 t
(1 row)

select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aa"}') q; →

 a
----
 aa
(1 row)

json_populate_recordset ( base anyelement, from_json json ) → setof anyelement

jsonb_populate_recordset ( base anyelement, from_json jsonb ) → setof anyelement

Étend le tableau JSON de haut niveau composĂ© d'objets en un ensemble de lignes ayant le type composite de l'argument base. Chaque Ă©lĂ©ment du tableau JSON est traitĂ© comme dĂ©crit ci-dessus pour json[b]_populate_record.

create type twoints as (a int, b int);

select * from json_populate_recordset(null::twoints, '[{"a":1,"b":2}, {"a":3,"b":4}]') →

 a | b
---+---
 1 | 2
 3 | 4
       

json_to_record ( json ) → record

jsonb_to_record ( jsonb ) → record

Étend l'objet JSON de haut niveau en une ligne ayant le type composite dĂ©fini par une clause AS. (Comme avec toutes les fonctions renvoyant record, la requĂȘte appelante doit explicitement dĂ©finir la structure de l'enregistrement avec une clause AS.) L'enregistrement en sortie est rempli avec les champs de l'objet JSON, de la mĂȘme façon que dĂ©crite ci-dessus pour json[b]_populate_record. Comme il n'existe aucune valeur record en entrĂ©e, les colonnes sans correspondance sont remplies avec des NULL.

create type myrowtype as (a int, b text);

select * from json_to_record('{"a":1, "b":[1,2,3], "c":[1,2,3], "e":"bar", "r": {"a": 123, "b": "a b c"}}') as x(a int, b text, c int[], d text, r myrowtype) →

 a |    b    |    c    | d |       r
---+---------+---------+---+---------------
 1 | [1,2,3] | {1,2,3} |   | (123,"a b c")
       

json_to_recordset ( json ) → setof record

jsonb_to_recordset ( jsonb ) → setof record

Étend le tableau JSON de haut niveau composĂ© d'objets en un ensemble de lignes ayant le type composite dĂ©fini par une clause AS. (Comme avec toutes les fonctions renvoyant record, la requĂȘte appelante doit explicitement dĂ©finir la structure de l'enregistrement avec une clause AS.) Chaque Ă©lĂ©ment du tableau JSON est traitĂ© comme dĂ©crit ci-dessus pour json[b]_populate_record.

select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) →

 a |  b
---+-----
 1 | foo
 2 |
       

jsonb_set ( target jsonb, path text[], new_value jsonb [, create_if_missing boolean ] ) → jsonb

Renvoie target avec l'élément désigné par path remplacé par new_value ou avec new_value ajouté si create_if_missing vaut true (ce qui est la valeur par défaut) et si l'élément désigné par path n'existe pas. Toutes les étapes précédentes dans le chemin doivent exister, sinon le target est renvoyé intact. Comme avec les opérateurs orientés chemin, les entiers négatifs qui apparaissent dans path se décomptent à partir de la fin des tableaux JSON. Si l'étape du dernier chemin est un index inexistant (hors limite) du tableau et si create_if_missing vaut true, la nouvelle valeur est ajoutée au début du tableau si l'index est négatif et à la fin du tableau s'il est positif.

jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false) → [{"f1": [2, 3, 4], "f2": null}, 2, null, 3]

jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}', '[2,3,4]') → [{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]

jsonb_set_lax ( target jsonb, path text[], new_value jsonb [, create_if_missing boolean [, null_value_treatment text ]] ) → jsonb

Si new_value n'est pas NULL, se comporte de façon identique Ă  jsonb_set. Sinon se comporte suivant la valeur de null_value_treatment qui doit ĂȘtre parmi 'raise_exception', 'use_json_null', 'delete_key' ou 'return_target'. Par dĂ©faut, il s'agit de 'use_json_null'.

jsonb_set_lax('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', null) → [{"f1": null, "f2": null}, 2, null, 3]

jsonb_set_lax('[{"f1":99,"f2":null},2]', '{0,f3}', null, true, 'return_target') → [{"f1": 99, "f2": null}, 2]

jsonb_insert ( target jsonb, path text[], new_value jsonb [, insert_after boolean ] ) → jsonb

Renvoie target avec new_value inséré. Si l'élément désigné par path est un élément de tableau, new_value sera inséré avant cet élément si insert_after vaut false (ce qui est la valeur par défaut) ou aprÚs si insert_after vaut true. Si l'élément désigné par path est un champ objet, new_value sera inséré seulement si l'objet ne contient pas déjà cette clé. Toutes les étapes précédentes dans le chemin doivent exister, sinon target est renvoyé non modifié. Comme avec les opérateurs orientés chemin, les nombres négatifs qui apparaissent dans path sont décomptés à partir de la fin des tableaux JSON. Si la derniÚre étape du chemin est un index hors limite de tableau, la nouvelle valeur est ajoutée au début du tableau si l'index est négatif ou à la fin du tableau s'il est positif.

jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') → {"a": [0, "new_value", 1, 2]}

jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true) → {"a": [0, 1, "new_value", 2]}

json_strip_nulls ( json ) → json

jsonb_strip_nulls ( jsonb ) → jsonb

Supprime tous les champs objets ayant des valeurs NULL à partir de la valeur JSON donnée, de façon récurvise. Les valeurs NULL qui ne sont pas des champs objets ne sont pas touchées.

json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]') → [{"f1":1},2,null,3]

jsonb_path_exists ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

VĂ©rifie si le chemin JSON renvoie des Ă©lĂ©ments de la valeur JSON spĂ©cifiĂ©e. (Cela n'est utile qu'avec les expressions de chemin JSON standard SQL, et non avec les expressions de vĂ©rification de prĂ©dicat, car celles-ci renvoient toujours une valeur.) Si l'argument vars est indiquĂ©, il doit correspondre Ă  un objet JSON, et ses champs fournissent des valeurs nommĂ©es Ă  substituer dans l'expression jsonpath. Si l'argument silent est indiquĂ© et vaut true, la fonction supprime les mĂȘmes erreurs que les opĂ©rateurs @? et @@.

jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}') → t

jsonb_path_match ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

Renvoie le rĂ©sultat de la vĂ©rification d'un prĂ©dicat de chemin JSON pour la valeur JSON spĂ©cifiĂ©e. (Cela n'est utile qu'avec les expressions de vĂ©rification de prĂ©dicat, et non avec les expressions de chemin JSON standard SQL, car cela Ă©chouera ou renverra NULL si le rĂ©sultat du chemin n'est pas une seule valeur boolĂ©enne.) Les arguments optionnels vars et silent agissent de la mĂȘme façon que pour jsonb_path_exists.

jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2,"max":4}') → t

jsonb_path_query ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → setof jsonb

Renvoie tous les Ă©lĂ©ments JSON renvoyĂ©s par le chemin JSON pour la valeur JSON spĂ©cifiĂ©e. Pour les expressions de chemin JSON standard SQL, il renvoie les valeurs JSON sĂ©lectionnĂ©es Ă  partir de target. Pour les expressions de vĂ©rification de prĂ©dicat, il renvoie le rĂ©sultat de la vĂ©rification du prĂ©dicat : true, false ou null. Les arguments optionnels vars et silent agissent de la mĂȘme façon que pour jsonb_path_exists.

select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}') →

 jsonb_path_query
------------------
 2
 3
 4
       

jsonb_path_query_array ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

Renvoie tous les Ă©lĂ©ments JSON renvoyĂ©s par le chemin JSON pour la valeur JSON spĂ©cifiĂ©e, sous la forme d'un tableau JSON. Les paramĂštres sont les mĂȘmes que pour jsonb_path_query

jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') → [2, 3, 4]

jsonb_path_query_first ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

Renvoie le premier Ă©lĂ©ment JSON renvoyĂ© par le chemin JSON pour la valeur JSON spĂ©cifiĂ©e ou NULL s'il n'y a pas de rĂ©sultat. Les paramĂštres sont les mĂȘmes que pour jsonb_path_query

jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') → 2

jsonb_path_exists_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

jsonb_path_match_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

jsonb_path_query_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → setof jsonb

jsonb_path_query_array_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

jsonb_path_query_first_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

Ces fonctions agissent comme leurs homologues dĂ©crits ci-dessus sans le suffixe _tz, sauf que ces fonctions acceptent la comparaison de valeurs date/heure qui nĂ©cessitent des conversions adaptĂ©es suivant le fuseau horaire. L'exemple ci-dessous requiert l'interprĂ©tation de la valeur date seule 2015-08-02 comme un horodatage avec fuseau horaire, pour que le rĂ©sultat dĂ©pende du paramĂ©trage actuel de TimeZone. Du fait de cette dĂ©pendance, ces fonctions sont marquĂ©es stables, ce qui signifie que ces fonctions ne peuvent pas ĂȘtre utilisĂ©es dans les index. Leurs homologues sont immuables, et donc peuvent ĂȘtre utilisĂ©s dans les index ; cependant, elles renverront des erreurs si on leur demande ce type de comparaison.

jsonb_path_exists_tz('["2015-08-01 12:00:00-05"]', '$[*] ? (@.datetime() < "2015-08-02".datetime())') → t

jsonb_pretty ( jsonb ) → text

Convertit la valeur JSON donnée en un texte proprement indenté.

jsonb_pretty('[{"f1":1, "f2":null}, 2]') →

[
    {
        "f1": 1,
        "f2": null
    },
    2
]
       

json_typeof ( json ) → text

jsonb_typeof ( jsonb ) → text

Renvoie le type de la valeur JSON de haut niveau sous la forme d'une chaĂźne de caractĂšres. Les types possibles sont object, array, string, number, boolean et null. (Le rĂ©sultat null ne doit pas ĂȘtre pris pour un NULL SQL ; voir les exemples.)

json_typeof('-123.4') → number

json_typeof('null'::json) → null

json_typeof(NULL::json) IS NULL → t


9.16.2. Le langage de chemin SQL/JSON #

Les expressions de chemin SQL/JSON indiquent les Ă©lĂ©ments Ă  rĂ©cupĂ©rer Ă  partir de donnĂ©es JSON, de façon similaire aux expressions XPath utilisĂ©es pour l'accĂšs SQL au XML. Dans PostgreSQL, les expressions de chemin sont implĂ©mentĂ©es sous la forme du type de donnĂ©es jsonpath et peuvent utiliser tout Ă©lĂ©ment dĂ©crit dans Section 8.14.7.

Les fonctions et opĂ©rateurs de requĂȘtes JSON passent l'expression de chemin fournie au moteur de chemin pour Ă©valuation. Si l'expression correspond Ă  la donnĂ©e JSON requĂȘtĂ©e, l'Ă©lĂ©ment JSON correspondant ou l'ensemble d'Ă©lĂ©ments est renvoyĂ©. S'il n'y a pas de correspondance, le rĂ©sultat sera NULL, false, ou une erreur, selon la fonction. Les expressions de chemin sont Ă©crites dans le langage de chemin SQL/JSON et peuvent inclure les expressions et fonctions arithmĂ©tiques.

Une expression de chemin consiste en une sĂ©quence d'Ă©lĂ©ments autorisĂ©s par le type de donnĂ©es jsonpath. L'expression de chemin est habituellement Ă©valuĂ©e de gauche Ă  droite, mais vous pouvez utiliser les parenthĂšses pour modifier l'ordre des opĂ©rations. Si l'Ă©valuation rĂ©ussit, une sĂ©quence d'Ă©lĂ©ments JSON est produite et le rĂ©sultat de l'Ă©valuation est renvoyĂ© Ă  la fonction de requĂȘte JSON qui termine le traitement indiquĂ©.

Pour faire rĂ©fĂ©rence Ă  la valeur JSON en cours de requĂȘtage (l'Ă©lĂ©ment de contexte), utilisez la variable $ dans l'expression de chemin. Le premier Ă©lement du chemin doit toujours ĂȘtre $. Elle peut ĂȘtre suivie par un ou plusieurs opĂ©rateurs d'accesseurs, qui descendent dans la structure JSON, Ă©tape par Ă©tape, pour rĂ©cupĂ©rer les sous-Ă©lĂ©ments de l'Ă©lĂ©ment de contexte. Chaque opĂ©rateur d'accĂšs agit sur le(s) rĂ©sultat(s) de l'Ă©tape d'Ă©valuation prĂ©cĂ©dente, produisant zĂ©ro, un ou plusieurs Ă©lĂ©ments de sortie Ă  partir de chaque Ă©lĂ©ment d'entrĂ©e.

Par exemple, supposez que vous ayez certaines donnĂ©es JSON Ă  partir d'un traqueur GPS que vous voulez analyser, tel que :

SELECT '{
  "track": {
    "segments": [
      {
        "location":   [ 47.763, 13.4034 ],
        "start time": "2018-10-14 10:05:14",
        "HR": 73
      },
      {
        "location":   [ 47.706, 13.2635 ],
        "start time": "2018-10-14 10:39:21",
        "HR": 135
      }
    ]
  }
}' AS json \gset
  

(L'exemple ci-dessus peut ĂȘtre copiĂ©-collĂ© dans psql pour prĂ©parer les exemples suivants. Ensuite, psql remplacera :'json' par une constante de chaĂźne de caractĂšre, contenant la valeur JSON.)

Pour rĂ©cupĂ©rer les segments de piste disponibles, vous avez besoin d'utiliser l'opĂ©rateur d'accesseur .key pour descendre Ă  travers les objets JSON tout autour, par exemple :

=> select jsonb_path_query(:'json', '$.track.segments');
                                                                         jsonb_path_query
-----------------------------------------------------------​-----------------------------------------------------------​---------------------------------------------
 [{"HR": 73, "location": [47.763, 13.4034], "start time": "2018-10-14 10:05:14"}, {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}]

Pour rĂ©cupĂ©rer le contenu d'un tableau, vous utilisez typiquement l'opĂ©rateur [*]. L'exemple suivant renverra les coordonnĂ©es d'emplacement pour tous les segments de piste disponibles :

=> select jsonb_path_query(:'json', '$.track.segments[*].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]

Ici, nous avons commencĂ© avec l'intĂ©gralitĂ© de la valeur d'entrĂ©e JSON ($), puis l'opĂ©rateur d'accĂšs .track a sĂ©lectionnĂ© l'objet JSON associĂ© Ă  la clĂ© d'objet "track", ensuite l'opĂ©rateur d'accĂšs .segments a sĂ©lectionnĂ© le tableau JSON associĂ© Ă  la clĂ© "segments" dans cet objet, puis l'opĂ©rateur d'accĂšs [*] a sĂ©lectionnĂ© chaque Ă©lĂ©ment de ce tableau (produisant une sĂ©rie d'Ă©lĂ©ments), enfin l'opĂ©rateur d'accĂšs .location a sĂ©lectionnĂ© le tableau JSON associĂ© Ă  la clĂ© "location" dans chacun de ces objets. Dans cet exemple, chacun de ces objets avait une clĂ© "location" ; maissi si l'un d'eux ne l'avait pas, l'opĂ©rateur d'accĂšs .location n'aurait pas donnĂ©e d'Ă©lement de sortie pour cet Ă©lĂ©ment d'entrĂ©e.

Pour renvoyer les coordonnĂ©es du premier segment seulement, vous pouvez indiquer l'indice correspondant dans l'opĂ©rateur []. Rappellez-vous que les indices de tableau JSON commencent Ă  0 :

=> select jsonb_path_query(:'json', '$.track.segments[0].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]

Le rĂ©sultat de chaque Ă©tape d'Ă©valuation de chemin peut ĂȘtre traitĂ© par un ou plusieurs opĂ©rateurs et mĂ©thodes jsonpath, listĂ©s dans Section 9.16.2.3. Chaque nom de mĂ©thode doit ĂȘtre prĂ©cĂ©dĂ© d'un point. Par exemple, vous pouvez obtenir la taille d'un tableau :

=> select jsonb_path_query(:'json', '$.track.segments.size()');
 jsonb_path_query
------------------
 2

D'autres exemples d'utilisation d'opĂ©rateurs et mĂ©thodes jsonpath Ă  l'intĂ©rieur d'expressions de chemins apparaissent ci-dessous dans Section 9.16.2.3.

Un chemin peut aussi contenir plusieurs expressions de filtre qui fonctionnent de façon similaire Ă  la clause WHERE en SQL. Une expression de filtre commence avec un point d'interrogation et fournit une condition entre parenthĂšses :

? (condition)
  

Les expressions de filtre doivent ĂȘtre Ă©crites juste aprĂšs l'Ă©tape d'Ă©valuation du chemin auquel elles s'appliquent. Le rĂ©sultat de cette Ă©tape est filtrĂ© pour inclure seulement les Ă©lĂ©ments qui satisfont la condition fournie. SQL/JSON dĂ©finit une logique Ă  trois valeurs, donc la condition peut produire true, false ou unknown. La valeur unknown joue le mĂȘme rĂŽle que le NULL SQL et peut ĂȘtre testĂ©e avec le prĂ©dicat is unknown. Les Ă©tapes suivantes d'Ă©valuation du chemin utilisent seulement les Ă©lĂ©ments pour lesquels l'expression de filtre renvoie true.

Les fonctions et opĂ©rateurs pouvant ĂȘtre utilisĂ©s dans des expressions de filtre sont listĂ©s dans Tableau 9.51. À l'intĂ©rieur d'une expression de filtre, la variable @ dĂ©note la valeur en cours de considĂ©ration (un rĂ©sultat de l'Ă©tape de chemin prĂ©cĂ©dente). Vous pouvez Ă©crire les opĂ©rateurs d'accesseurs aprĂšs @ pour rĂ©cupĂ©rer les Ă©lĂ©ments du composant.

Par exemple, supposez que vous vouliez rĂ©cupĂ©rer toutes les valeurs de frĂ©quence cardiaque supĂ©rieures Ă  130. Vous pouvez le faire ainsi :

=> select jsonb_path_query(:'json', '$.track.segments[*].HR ? (@ > 130)');
 jsonb_path_query
------------------
 135

Pour obtenir les heures de dĂ©but des segments ayant une telle valeur, vous devez filtrer les segments incompatibles avant de sĂ©lectionner les heures de dĂ©but, donc l'expression de filtre est appliquĂ©e Ă  l'Ă©tape prĂ©cĂ©dente, et le chemin utilisĂ© dans la condition est diffĂ©rent :

=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.HR > 130)."start time"');
   jsonb_path_query
-----------------------
 "2018-10-14 10:39:21"

Vous pouvez utiliser plusieurs expressions de filtre en sĂ©quence, si nĂ©cessaire. L'expression suivante sĂ©lectionne les heures de dĂ©but de tous les segments qui contiennent des emplacements avec les bonnes coordonnĂ©es et les valeurs hautes de frĂ©quence cardiaque :

=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"');
   jsonb_path_query
-----------------------
 "2018-10-14 10:39:21"

Il est aussi autorisĂ© d'utiliser des expressions de filtre Ă  diffĂ©rents niveaux de profondeur. L'exemple suivant filtre tout d'abord tous les segments par emplacement, puis renvoie les valeurs hautes de frĂ©quence cardiaque sur ces segments, si disponibles :

=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)');
 jsonb_path_query
------------------
 135

Vous pouvez aussi imbriquer les expressions de filtre. Cet exemple renvoie la taille du chemin s'il contient des segments ayant des valeurs de frĂ©quence cardiaque Ă©levĂ©es ou une sĂ©quence vide sinon :

=> select jsonb_path_query(:'json', '$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()');
 jsonb_path_query
------------------
 2

9.16.2.1. DĂ©viations du standard SQL #

L'implĂ©mentation PostgreSQL du langage de chemin SQL/JSON prĂ©sente les diffĂ©rences suivantes sur le standard SQL/JSON :

9.16.2.1.1. Expressions de la vĂ©rification du prĂ©dicat boolĂ©en #

Étant une extension du standard SQL, une expression de chemin PostgreSQL peut ĂȘtre un prĂ©dicat boolĂ©en, alors que le standard SQL autorise les prĂ©dicats uniquement dans les filtres. Tandis que les expressions de chemin conformes au standard SQL renvoient les Ă©lĂ©ments pertinents de la valeur JSON interrogĂ©e, les expressions de vĂ©rification de prĂ©dicat renvoient le rĂ©sultat unique, du type jsonb du prĂ©dicat avec trois valeurs possibles : true, false ou null. Par exemple, nous pourrions Ă©crire cette expression de filtre qui est conforme au standard SQL :

=> select jsonb_path_query(:'json', '$.track.segments ?(@[*].HR > 130)');
                                jsonb_path_query
-----------------------------------------------------------​----------------------
 {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}

L'expression de vĂ©rification de prĂ©dicat similaire renvoie simplement true, indiquant qu'une correspondance existe :

=> select jsonb_path_query(:'json', '$.track.segments[*].HR > 130');
 jsonb_path_query
------------------
 true

Note

Les expressions de vĂ©rification de prĂ©dicat sont requises dans l'opĂ©rateur @@ (et la fonction jsonb_path_match), et ne doivent pas ĂȘtre utilisĂ©es avec l'opĂ©rateur @? (ou la fonction jsonb_path_exists).

9.16.2.1.2. InterprĂ©tation des expressions rĂ©guliĂšres #

Il existe de lĂ©gĂšres diffĂ©rences dans l'interprĂ©tation des modĂšles d'expressions rĂ©guliĂšres utilisĂ©s dans les filtres like_regex, comme dĂ©crit dans Section 9.16.2.4.

9.16.2.2. Modes strict et permissif #

Quand vous requĂȘtez des donnĂ©es JSON, l'expression de chemin pourrait ne pas correspondre Ă  la structure de donnĂ©es JSON actuelle. Une tentative d'accĂ©der Ă  un membre inexistant d'un objet ou d'un Ă©lĂ©ment d'un tableau est dĂ©finie comme une erreur de structure. Les expressions de chemin SQL/JSON ont deux modes pour la gestion des erreurs de structure :

  • lax (permissif, par dĂ©faut) -- le moteur de chemin adapte implicitement la donnĂ©e requĂȘtĂ©e au chemin spĂ©cifiĂ©. Toute erreur de structure qui ne peut ĂȘtre corrigĂ©e comme dĂ©crit ci-dessous est supprimĂ©e, ne produisant aucune correspondance.

  • strict -- si une erreur de structure survient, une erreur est levĂ©e.

Le mode permissif facilite la correspondance d'un document JSON et d'une expression de chemin si la donnĂ©e JSON n'est pas conforme au schĂ©ma attendu. Si un opĂ©rande ne correspond pas aux demandes d'une opĂ©ration particuliĂšre, il peut ĂȘtre automatiquement intĂ©grĂ© Ă  un tableau SQL/JSON ou dĂ©ballĂ© en convertissant ses Ă©lĂ©ments en une sĂ©quence SQL/JSON avant de rĂ©aliser cette opĂ©ration. De plus, les opĂ©rateurs de comparaison dĂ©ballent automatiquement leurs opĂ©randes dans le mode permissif, donc vous pouvez directement comparer les tableaux SQL/JSON. Un tableau de taille 1 est considĂ©rĂ© Ă©gal Ă  son seul Ă©lĂ©ment. Le dĂ©ballage automatique n'est pas rĂ©alisĂ© quand :

  • L'expression de chemin contient les mĂ©thodes type() ou size() qui renvoient respectivement le type et le nombre d'Ă©lĂ©ments dans le tableau.

  • Les donnĂ©es JSON requĂȘtĂ©es contiennent des tableaux imbriquĂ©s. Dans ce cas, seul le tableau externe est dĂ©ballĂ© alors que les tableaux internes restent inchangĂ©s. De ce fait, le dĂ©ballage implicite peut seulement descendre d'un niveau Ă  chaque Ă©tape d'Ă©valuation du chemin.

Par exemple, lors du requĂȘtage de donnĂ©es GPS ci-dessus, vous pouvez faire abstraction du fait qu'il stocke un tableau de segments en utilisant le mode permissif :

=> select jsonb_path_query(:'json', 'lax $.track.segments.location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]

Dans le mode strict, le chemin spĂ©cifiĂ© doit correspondre exactement Ă  la structure du document JSON requĂȘtĂ©, donc utiliser cette expression de chemin causera une erreur :

=> select jsonb_path_query(:'json', 'strict $.track.segments.location');
ERROR:  jsonpath member accessor can only be applied to an object

Pour obtenir le mĂȘme rĂ©sultat qu'en mode lax, vous devez dĂ©baller explicitement le tableau segments :

=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]

Le comportement de dĂ©capsulation (unwrapping) en mode lax peut entraĂźner des rĂ©sultats surprenants. Par exemple, la requĂȘte suivante utilisant l'opĂ©rateur d'accĂšs .** sĂ©lectionne chaque valeur HR deux fois :

=> select jsonb_path_query(:'json', 'lax $.**.HR');
 jsonb_path_query
------------------
 73
 135
 73
 135

Ceci survient parce que l'accesseur .** sĂ©lectionne Ă  la fois le tableau de segments et chacun de ses Ă©lĂ©ments, alors que l'accesseur .HR dĂ©balle automatiquement les tableaux lors de l'utilisation du mode non strict. Pour Ă©viter des rĂ©sultats surprenants, nous recommandons d'utiliser l'accesseur .** uniquement dans le mode strict. la requĂȘte suivant sĂ©lectionne chaque valeur HR une seule fois :

=> select jsonb_path_query(:'json', 'strict $.**.HR');
 jsonb_path_query
------------------
 73
 135

La dĂ©capsulation (unwrapping) des tableaux peut Ă©galement entraĂźner des rĂ©sultats inattendus. ConsidĂ©rez cet exemple, qui sĂ©lectionne tous les tableaux location :

=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]
(2 rows)

Comme prĂ©vu, il renvoie les tableaux complets. Mais l'application d'une expression de filtre entraĂźne la dĂ©capsulation (unwrapping) des tableaux pour Ă©valuer chaque Ă©lĂ©ment, ne renvoyant que les Ă©lĂ©ments qui correspondent Ă  l'expression :

=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location ?(@[*] > 15)');
 jsonb_path_query
------------------
 47.763
 47.706
(2 rows)

Ceci malgrĂ© le fait que les tableaux complets sont sĂ©lectionnĂ©s par l'expression de chemin. Utilisez le mode strict pour restaurer la sĂ©lection des tableaux :

=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location ?(@[*] > 15)');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]
(2 rows)

9.16.2.3. OpĂ©rateurs et mĂ©thodes de chemin SQL/JSON #

Tableau 9.50 montre les opĂ©rateurs et mĂ©thodes disponibles pour jsonpath. Notez que, bien que les opĂ©rateurs et mĂ©thodes unaires puissent ĂȘtre appliquĂ©s Ă  de nombreuses valeurs rĂ©sultant d'une Ă©tape de chemin prĂ©cĂ©dente, les opĂ©rateurs binaires (addition etc.) peuvent seulement ĂȘtre appliquĂ©s Ă  des valeurs seules. En mode lax, les mĂ©thodes appliquĂ©es Ă  un tableau seront exĂ©cutĂ©es pour chaque valeur du tableau. Les exceptions sont : .type() et .size(), qui s'appliquent au tableau lui-mĂȘme.

Tableau 9.50. OpĂ©rateurs et mĂ©thodes jsonpath

Opérateur/Méthode

Description

Exemple(s)

number + number → number

Addition

jsonb_path_query('[2]', '$[0] + 3') → 5

+ number → number

Plus unaire (pas d'opĂ©ration) ; contrairement Ă  l'addition, ceci peut itĂ©rer sur plusieurs valeurs

jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') → [2, 3, 4]

number - number → number

Soustraction

jsonb_path_query('[2]', '7 - $[0]') → 5

- number → number

NĂ©gation ; contrairement Ă  la soustraction, ceci peut itĂ©rer sur plusieurs valeurs

jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') → [-2, -3, -4]

number * number → number

Multiplication

jsonb_path_query('[4]', '2 * $[0]') → 8

number / number → number

Division

jsonb_path_query('[8.5]', '$[0] / 2') → 4.2500000000000000

number % number → number

Modulo (reste)

jsonb_path_query('[32]', '$[0] % 10') → 2

value . type() → string

Type de l'élément JSON (voir json_typeof)

jsonb_path_query_array('[1, "2", {}]', '$[*].type()') → ["number", "string", "object"]

value . size() → number

Taille de l'élément JSON (nombre d'éléments d'un tableau, ou 1 si ce n'est pas un tableau)

jsonb_path_query('{"m": [11, 15]}', '$.m.size()') → 2

value . boolean() → boolean

Valeur booléenne convertie à partir d'un booléen, d'un nombre ou d'une chaßne JSON

jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()') → [true, true, false]

value . string() → string

Valeur de type chaßne de caractÚres convertie en un booléen, nombre, chaßne ou horodatage JSON

jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()') → ["1.23", "xyz", "false"]

jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()') → "2023-08-15T12:34:56"

value . double() → number

Nombre flottant approximatif converti en nombre JSON ou en chaĂźne

jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') → 3.8

number . ceiling() → number

Entier le plus proche, plus grand ou égal au nombre donné

jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') → 2

number . floor() → number

Entier le plus proche, plus petit ou égal au nombre donné

jsonb_path_query('{"h": 1.7}', '$.h.floor()') → 1

number . abs() → number

Valeur absolue du nombre donné

jsonb_path_query('{"z": -0.3}', '$.z.abs()') → 0.3

value . bigint() → bigint

Grande valeur entiĂšre convertie Ă  partir d'un nombre JSON ou d'une chaĂźne JSON

jsonb_path_query('{"len": "9876543219"}', '$.len.bigint()') → 9876543219

value . decimal( [ precision [ , scale ] ] ) → decimal

Valeur dĂ©cimale arrondie convertie Ă  partir d'un nombre JSON ou d'une chaĂźne JSON (precision et scale doivent ĂȘtre des valeurs entiĂšres).

jsonb_path_query('1234.5678', '$.decimal(6, 2)') → 1234.57

value . integer() → integer

Valeur entiĂšre convertie Ă  partir d'un nombre JSON ou d'une chaĂźne JSON

jsonb_path_query('{"len": "12345"}', '$.len.integer()') → 12345

value . number() → numeric

Valeur numérique convertie à partir d'un nombre JSON ou d'une chaßne JSON

jsonb_path_query('{"len": "123.45"}', '$.len.number()') → 123.45

string . datetime() → datetime_type (voir note)

Valeur date/heure convertie en chaĂźne

jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())') → "2015-8-1"

string . datetime(template) → datetime_type (voir note)

Valeur date/heure convertie en une chaßne en utilisant le modÚle to_timestamp indiqué

jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') → ["12:30:00", "18:40:00"]

string . date() → date

Valeur date convertie en chaĂźne

jsonb_path_query('"2023-08-15"', '$.date()') → "2023-08-15"

string . time() → time without time zone

Horodatage sans fuseau horaire converti en chaĂźne

jsonb_path_query('"12:34:56"', '$.time()') → "12:34:56"

string . time(precision) → time without time zone

Valeur horaire sans fuseau horaire convertie en chaßne de caractÚres, avec les secondes fractionnelles converties à la précision demandée.

jsonb_path_query('"12:34:56.789"', '$.time(2)') → "12:34:56.79"

string . time_tz() → time with time zone

Valeur horaire avec fuseau horaire convertie Ă  partir d'une chaĂźne de caractĂšres.

jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()') → "12:34:56+05:30"

string . time_tz(precision) → time with time zone

Valeur horaire avec fuseau horaire convertie à partir d'une chaßne de caractÚres, avec les secondes fractionnelles converties à la précision demandée.

jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)') → "12:34:56.79+05:30"

string . timestamp() → timestamp without time zone

Horodatage sans fuseau horaire converti Ă  partir d'une chaĂźne

jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()') → "2023-08-15T12:34:56"

string . timestamp(precision) → timestamp without time zone

Horodatage sans fuseau horaire converti à partir d'une chaßne, avec des secondes fractionnaires ajustées à la précision donnée.

jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)') → "2023-08-15T12:34:56.79"

string . timestamp_tz() → timestamp with time zone

Horodatage avec fuseau horaire converti Ă  partir d'une chaĂźne

jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()') → "2023-08-15T12:34:56+05:30"

string . timestamp_tz(precision) → timestamp with time zone

Horodatage avec fuseau horaire converti à partir d'une chaßne, avec des secondes fractionnaires ajustées à la précision donnée.

jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)') → "2023-08-15T12:34:56.79+05:30"

object . keyvalue() → array

Les paires clĂ©-valeur de l'objet, reprĂ©sentĂ©es sous la forme d'un tableau d'objets contenant trois champs : "key", "value" et "id" ; "id" est un identifiant unique de l'objet auquel la paire clĂ©-valeur appartient

jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') → [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}]


Note

Le type de rĂ©sultat des mĂ©thodes datetime() et datetime(template) peut ĂȘtre date, timetz, time, timestamptz ou timestamp. Les deux mĂ©thodes dĂ©terminent dynamiquement le type du rĂ©sultat.

La mĂ©thode datetime() trie en sĂ©quence pour faire correspondre sa chaĂźne en entrĂ©e aux formats ISO pour les types date, timetz, time, timestamptz et timestamp. Elle s'arrĂȘte au premier format correspondant et Ă©met le type de donnĂ©es correspondant.

La méthode datetime(template) détermine le type de résultat suivant les champs utilisés dans la chaßne modÚle fournie.

Les mĂ©thodes datetime() et datetime(template) utilisent les mĂȘmes rĂšgles d'analyse que la fonction SQL to_timestamp (voir Section 9.8), avec trois exceptions. Tout d'abord, ces mĂ©thodes n'autorisent pas les motifs de modĂšle sans correspondance. Ensuite, seuls les sĂ©parateurs suivants sont autorisĂ©s dans la chaĂźne modĂšle : signe moins, point, barre oblique, virgule, apostrophe, point-virgule, deux-points et espace. Enfin, les sĂ©parateurs dans la chaĂźne modĂšle doivent correspondre exactement Ă  la chaĂźne en entrĂ©e.

Si diffĂ©rents types date/heure doivent ĂȘtre comparĂ©s, une conversion implicite est appliquĂ©e. Une valeur date peut ĂȘtre convertie en timestamp ou timestamptz, une valeur timestamp peut ĂȘtre convertie en timestamptz, et une valeur time en timetz. NĂ©anmoins, toutes sauf la premiĂšre de ces conversions dĂ©pendent du paramĂ©trage actuel de TimeZone, et de ce fait peuvent seulement ĂȘtre rĂ©alisĂ©es Ă  travers les fonctions jsonpath sensibles au fuseau horaire. De mĂȘme, d'autres mĂ©thodes liĂ©es aux dates/heures qui convertissent des chaĂźnes en types de date/heure effectuent Ă©galement cette conversion, qui peut impliquer le paramĂštre TimeZone actuel. Par consĂ©quent, ces conversions ne peuvent ĂȘtre effectuĂ©es que si les fonctions jsonpath sont conscientes du fuseau horaire.

Tableau 9.51 montre les Ă©lĂ©ments d'expression de filtre disponibles.

Tableau 9.51. Ă‰lĂ©ments d'expression de filtre jsonpath

Prédicat/valeur

Description

Exemple(s)

value == value → boolean

Comparaison d'égalité (ceci, et les autres opérateurs de comparaison, fonctionnent sur toutes les valeurs scalaires JSON)

jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == 1)') → [1, 1]

jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == "a")') → ["a"]

value != value → boolean

value <> value → boolean

Comparaison de non égalité

jsonb_path_query_array('[1, 2, 1, 3]', '$[*] ? (@ != 1)') → [2, 3]

jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <> "b")') → ["a", "c"]

value < value → boolean

Comparaison inférieur

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ < 2)') → [1]

value <= value → boolean

Comparaison inférieur ou égal

jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <= "b")') → ["a", "b"]

value > value → boolean

Comparaison supérieur

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ > 2)') → [3]

value >= value → boolean

Comparaison supérieur ou égal

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ >= 2)') → [2, 3]

true → boolean

Constante JSON true

jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == true)') → {"name": "Chris", "parent": true}

false → boolean

Constante JSON false

jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == false)') → {"name": "John", "parent": false}

null → value

Constante JSON null (notez que, contrairement au SQL, la comparaison avec null fonctionne normalement)

jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') → "Mary"

boolean && boolean → boolean

AND booléen

jsonb_path_query('[1, 3, 7]', '$[*] ? (@ > 1 && @ < 5)') → 3

boolean || boolean → boolean

OR booléen

jsonb_path_query('[1, 3, 7]', '$[*] ? (@ < 1 || @ > 5)') → 7

! boolean → boolean

NOT booléen

jsonb_path_query('[1, 3, 7]', '$[*] ? (!(@ < 5))') → 7

boolean is unknown → boolean

Teste si une condition booléenne est unknown.

jsonb_path_query('[-1, 2, 7, "foo"]', '$[*] ? ((@ > 0) is unknown)') → "foo"

string like_regex string [ flag string ] → boolean

Teste si le premier opĂ©rande correspond Ă  l'expression rationnelle donnĂ©e par le deuxiĂšme opĂ©rande, optionnellement avec les modifications dĂ©crites par une chaĂźne avec les caractĂšres de flag (voir Section 9.16.2.4).

jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') → ["abc", "abdacb"]

jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c" flag "i")') → ["abc", "aBdC", "abdacb"]

string starts with string → boolean

Vérifie si le deuxiÚme opérande est une sous-chaßne initiale du premier opérande.

jsonb_path_query('["John Smith", "Mary Stone", "Bob Johnson"]', '$[*] ? (@ starts with "John")') → "John Smith"

exists ( path_expression ) → boolean

Vérifie si une expression de chemin correspond à au moins un élément SQL/JSON. Renvoie unknown si l'expression de chemin entraßnerait une erreur ; le deuxiÚme exemple utilise cela pour éviter une erreur de type clé inexistante en utilisant le mode strict.

jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] > 2)))') → [2, 4]

jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name') → []


9.16.2.4. Expressions rationnelles SQL/JSON #

Les expressions de chemin SQL/JSON permettent de faire correspondre du texte Ă  une expression rĂ©guliĂšre avec le filtre like_regex. Par exemple, la requĂȘte de chemin SQL/JSON suivante ferait correspondre, de maniĂšre insensible Ă  la casse, toutes les chaĂźnes d'un tableau commençant par une voyelle française :

$[*] ? (@ like_regex "^[aeiouy]" flag "i")

La chaĂźne de flag optionnelle peut inclure un ou plusieurs des caractĂšres suivants : i pour une correspondance insensible Ă  la casse, m pour permettre Ă  ^ et $ de correspondre aux nouvelles lignes, s pour permettre Ă  . de correspondre Ă  une nouvelle ligne, q pour citer l'ensemble du motif (rĂ©duisant le comportement Ă  une simple correspondance de sous-chaĂźne).

La norme SQL/JSON emprunte sa dĂ©finition pour les expressions rĂ©guliĂšres Ă  l'opĂ©rateur LIKE_REGEX, qui utilise Ă  son tour la norme XQuery. PostgreSQL ne prend actuellement pas en charge l'opĂ©rateur LIKE_REGEX. Par consĂ©quent, le filtre like_regex est implĂ©mentĂ© en utilisant le moteur d'expressions rĂ©guliĂšres POSIX dĂ©crit dans Section 9.7.3. Cela conduit Ă  plusieurs petites divergences par rapport au comportement standard SQL/JSON, qui sont cataloguĂ©es dans Section 9.7.3.8. Notez toutefois que les incompatibilitĂ©s de lettres du drapeau (flag) dĂ©crites ici ne s'appliquent pas Ă  SQL/JSON, car il traduit les lettres du drapeau XQuery pour correspondre Ă  ce que le moteur POSIX attend.

Gardez Ă  l'esprit que l'argument de motif de like_regex est une chaĂźne littĂ©rale de chemin JSON, Ă©crite selon les rĂšgles donnĂ©es dans Section 8.14.7. Cela signifie en particulier que tous les antislashs que vous souhaitez utiliser dans l'expression rĂ©guliĂšre doivent ĂȘtre doublĂ©s. Par exemple, pour faire correspondre les valeurs de chaĂźne du document racine qui ne contiennent que des chiffres :

$.* ? (@ like_regex "^\\d+$")

9.16.3. Fonctions de requĂȘtage SQL/JSON #

Les fonctions SQL/JSON JSON_EXISTS(), JSON_QUERY() et JSON_VALUE() dĂ©crites dans Tableau 9.52 peuvent ĂȘtre utilisĂ©es pour interroger des documents JSON. Chacune de ces fonctions applique une path_expression (la requĂȘte de chemin SQL/JSON) Ă  un context_item (le document). Voir Section 9.16.2 pour plus de dĂ©tails sur ce que peut contenir une path_expression. Le path_expression peut aussi rĂ©fĂ©rencer des variables, dont les valeurs sont indiquĂ©es avec leur nom respectif dans la clause PASSING qui est acceptĂ©e par chaque fonction. context_item peut ĂȘtre une valeur jsonb ou une chaĂźne de caractĂšres convertible en jsonb.

Tableau 9.52. Fonctions de requĂȘte SQL/JSON

Signature de la fonction

Description

Exemple(s)

JSON_EXISTS (
context_item, path_expression
[ PASSING { value AS varname } [, ...]]
[{ TRUE | FALSE | UNKNOWN | ERROR } ON ERROR ]) → boolean

  • Renvoie true si le path_expression SQL/JSON appliquĂ©e au context_item produit des Ă©lĂ©ments. Sinon renvoie false.

  • La clause ON ERROR spĂ©cifie le comportement en cas d'erreur lors de l'Ă©valuation de path_expression. Indiquer ERROR causera le renvoi d'une erreur avec le message appropriĂ©. Les autres options incluent le renvoi de valeurs boolĂ©ennes FALSE ou TRUE ou la valeur UNKNOWN qui est en rĂ©alitĂ© un NULL SQL. Par dĂ©faut, quand aucune clause ON ERROR n'est indiquĂ©e, la valeur boolĂ©enne FALSE est renvoyĂ©e.

Exemples :

JSON_EXISTS(jsonb '{"key1": [1,2,3]}', 'strict $.key1[*] ? (@ > $x)' PASSING 2 AS x) → t

JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'lax $.a[5]' ERROR ON ERROR) → f

JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'strict $.a[5]' ERROR ON ERROR) →

ERROR:  jsonpath array subscript is out of bounds

JSON_QUERY (
context_item, path_expression
[ PASSING { value AS varname } [, ...]]
[ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ]
[ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ]
[ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
[ { ERROR | NULL | EMPTY { [ ARRAY ] | OBJECT } | DEFAULT expression } ON EMPTY ]
[ { ERROR | NULL | EMPTY { [ ARRAY ] | OBJECT } | DEFAULT expression } ON ERROR ]) → jsonb

  • Renvoie le rĂ©sultat de l'application du path_expression SQL/JSON au context_item.

  • Par dĂ©faut, le rĂ©sultat est renvoyĂ© comme une valeur de type jsonb, bien que la clause RETURNING peut ĂȘtre utilisĂ© pour renvoyer certains autres types vers lesquels ils peuvent ĂȘtre convertis.

  • Si l'expression du chemin peut renvoyer plusieurs valeurs, il pourrait ĂȘtre nĂ©cessaire des les englober en utilisant la clause WITH WRAPPER pour la transformer en chaĂźne JSON valide. Le comportement par dĂ©faut revient Ă  ne pas les englober, comme si WITHOUT WRAPPER Ă©tait indiquĂ©. La clause WITH WRAPPER est considĂ©rĂ© comme signifiant WITH UNCONDITIONAL WRAPPER, ce qui signifie que mĂȘme une valeur seule de rĂ©sultat sera englobĂ©e. Pour appliquer l'englobage uniquement quand plusieurs valeurs sont prĂ©sentes, prĂ©cisez WITH CONDITIONAL WRAPPER. Obtenir plusieurs valeurs dans le rĂ©sultat sera traitĂ© comme une erreur si WITHOUT WRAPPER est indiquĂ©.

  • Si le rĂ©sultat est une chaĂźne scalaire, par dĂ©faut, la valeur renvoyĂ©e sera entourĂ©e de guillemets simples, en faisant une valeur JSON valide. Cela peut ĂȘtre rendu explicite en spĂ©cifiant KEEP QUOTES. Inversement, les guillemets peuvent ĂȘtre omis en spĂ©cifiant OMIT QUOTES. Pour s'assurer que le rĂ©sultat est une valeur JSON valide, OMIT QUOTES ne peut pas ĂȘtre indiquĂ© quand WITH WRAPPER est aussi prĂ©cisĂ©.

    La clause ON EMPTY indique le comportement si l'évaluation de path_expression renvoie un ensemble vide. La clause ON ERROR indique le comportement si une erreur survient lors de l'évaluation de path_expression, lors de la conversion de la valeur du résultat dans le type de RETURNING, ou lors de l'évaluation de l'expression ON EMPTY si l'évaluation de path_expression renvoie un ensemble vide.

    Pour ON EMPTY et ON ERROR, indiquer ERROR causera le renvoi d'une erreur avec le message appropriĂ©. D'autres options incluent le renvoi d'un NULL SQL, d'un tableau vide (EMPTY [ARRAY]), d'un objet vide (EMPTY OBJECT), ou d'une expression utilisateur (DEFAULT expression) qui peut ĂȘtre convertie en jsonb ou dans le type spĂ©cifiĂ© par RETURNING. La valeur par dĂ©faut quand ON EMPTY ou ON ERROR n'est pas indiquĂ© est de renvoyer une valeur SQL NULL.

Exemples :

JSON_QUERY(jsonb '[1,[2,3],null]', 'lax $[*][$off]' PASSING 1 AS off WITH CONDITIONAL WRAPPER) → [3]

JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' OMIT QUOTES) → [1, 2]

JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' RETURNING int[] OMIT QUOTES ERROR ON ERROR) →

ERROR:  malformed array literal: "[1, 2]"
DETAIL:  Missing "]" after array dimensions.

JSON_VALUE (
context_item, path_expression
[ PASSING { value AS varname } [, ...]]
[ RETURNING data_type ]
[ { ERROR | NULL | DEFAULT expression } ON EMPTY ]
[ { ERROR | NULL | DEFAULT expression } ON ERROR ]) → text

  • Renvoie le rĂ©sultat de l'application du path_expression SQL/JSON au context_item.

  • Utilisez seulement JSON_VALUE() si la valeur extraite doit ĂȘtre un Ă©lĂ©ment scalaire SQL/JSON simple ; la rĂ©cupĂ©ration de plusieurs valeurs sera traitĂ©e comme une erreur. Si vous vous attendez Ă  ce que la valeur extraite soit un objet ou un tableau, utilisez Ă  la place la fonction JSON_QUERY.

  • Par dĂ©faut, le rĂ©sultat, qui doit ĂȘtre une valeur scalaire simple, est renvoyĂ© comme une valeur de type text, bien que la clause RETURNING puisse ĂȘtre utilisĂ©e pour renvoyer d'autres types auxquels il peut ĂȘtre converti.

  • Les clauses ON ERROR et ON EMPTY ont des sĂ©mantiques similaires Ă  celles mentionnĂ©es dans la description de JSON_QUERY, sauf si l'ensemble de valeurs renvoyĂ©es Ă  la place d'une erreur est diffĂ©rent.

  • Notez que les chaĂźnes scalaires renvoyĂ©es par JSON_VALUE ont toujours leurs guillemets supprimĂ©s, ce qui Ă©quivaut Ă  spĂ©cifier OMIT QUOTES dans JSON_QUERY.

Exemples :

JSON_VALUE(jsonb '"123.45"', '$' RETURNING float) → 123.45

JSON_VALUE(jsonb '"03:04 2015-02-01"', '$.datetime("HH24:MI YYYY-MM-DD")' RETURNING date) → 2015-02-01

JSON_VALUE(jsonb '[1,2]', 'strict $[$off]' PASSING 1 as off) → 2

JSON_VALUE(jsonb '[1,2]', 'strict $[*]' DEFAULT 9 ON ERROR) → 9


Note

L'expression context_item est convertie en jsonb par une conversion implicite si l'expression n'est pas déjà de type jsonb. Notez, néanmoins, que toute erreur d'analyse survenant pendant cette conversion, est renvoyée sans condition, c'est-à-dire ne sont pas gérées suivant la clause ON ERROR implicite ou explicite.

Note

JSON_VALUE() renvoie un NULL SQL si path_expression renvoie un JSON null, alors que JSON_QUERY() renvoie le null JSON tel quel.

9.16.4. JSON_TABLE #

JSON_TABLE est une fonction SQL/JSON qui interroge les donnĂ©es JSON et prĂ©sente les rĂ©sultats sous forme de vue relationnelle, qui peut ĂȘtre consultĂ©e comme une table SQL normale. Vous pouvez utiliser JSON_TABLE dans la clause FROM d'une instruction SELECT, UPDATE ou DELETE et comme source de donnĂ©es dans une instruction MERGE.

En prenant des données JSON en entrée, JSON_TABLE utilise une expression de chemin JSON pour extraire une partie des données fournies à utiliser comme motif de ligne pour la vue construite. Chaque valeur SQL/JSON donnée par le modÚle de ligne sert de source pour une ligne distincte dans la vue construite.

Pour diviser le motif de ligne en colonnes, JSON_TABLE fournit la clause COLUMNS qui dĂ©finit le schĂ©ma de la vue créée. Pour chaque colonne, une expression de chemin JSON distincte peut ĂȘtre spĂ©cifiĂ©e pour ĂȘtre Ă©valuĂ©e par rapport au motif de ligne afin d'obtenir une valeur SQL/JSON qui deviendra la valeur de la colonne spĂ©cifiĂ©e dans une ligne de sortie donnĂ©e.

Les donnĂ©es JSON stockĂ©es Ă  un niveau imbriquĂ© du modĂšle de ligne peuvent ĂȘtre extraites Ă  l'aide de la clause NESTED PATH. Chaque clause NESTED PATH peut ĂȘtre utilisĂ©e pour gĂ©nĂ©rer une ou plusieurs colonnes Ă  partir des donnĂ©es d'un niveau imbriquĂ© du motif de ligne. Ces colonnes peuvent ĂȘtre spĂ©cifiĂ©es Ă  l'aide d'une clause COLUMNS semblable Ă  la clause COLUMNS de niveau le plus haut. Les lignes construites Ă  partir des colonnes imbriquĂ©es sont appelĂ©es lignes enfants et sont jointes aux lignes construites Ă  partir des colonnes spĂ©cifiĂ©es dans la clause COLUMNS parente pour obtenir la ligne dans la vue finale. Les colonnes enfants elles-mĂȘmes peuvent contenir une spĂ©cification NESTED PATH, permettant ainsi d'extraire des donnĂ©es situĂ©es Ă  des niveaux d'imbrication arbitraires. Les colonnes produites par plusieurs NESTED PATH au mĂȘme niveau sont considĂ©rĂ©es comme des frĂšres et sƓurs et leurs lignes sont combinĂ©es Ă  l'aide de UNION aprĂšs la jonction avec la ligne parente.

Les lignes produites par JSON_TABLE sont jointes latéralement à la ligne qui les a générées, de sorte que vous n'avez pas besoin de joindre explicitement la vue construite avec la table d'origine contenant les données JSON.

La syntaxe est :

JSON_TABLE (
    context_item, path_expression [ AS json_path_name ] [ PASSING { value AS varname } [, ...] ]
    COLUMNS ( json_table_column [, ...] )
    [ { ERROR | EMPTY [ARRAY]} ON ERROR ]
)


oĂč json_table_column vaut :

  name FOR ORDINALITY
  | name type
        [ FORMAT JSON [ENCODING UTF8]]
        [ PATH path_expression ]
        [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ]
        [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
        [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON EMPTY ]
        [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON ERROR ]
  | name type EXISTS [ PATH path_expression ]
        [ { ERROR | TRUE | FALSE | UNKNOWN } ON ERROR ]
  | NESTED [ PATH ] path_expression [ AS json_path_name ] COLUMNS ( json_table_column [, ...] )

Chaque élement de syntaxe est décrit ci-dessous avec plus de détails.

context_item, path_expression [ AS json_path_name ] [ PASSING { value AS varname } [, ...]]

context_item indique le document en entrĂ©e Ă  requĂȘter, path_expression est une expression de chemin SQL/JSON dĂ©finissant la requĂȘte, et json_path_name est un nom optionnel pour path_expression. La clause optionnelle PASSING fournit des valeurs aux donnĂ©es pour les variables mentionnĂ©es dans path_expression. Le rĂ©sultat de l'Ă©valuation des donnĂ©es en entrĂ©e en utilisant les Ă©lĂ©ments dĂ©jĂ  mentionnĂ©s est appelĂ© The result of the input data evaluation using the aforementioned elements row pattern, qui est utilisĂ© comme source pour les valeurs de ligne dans la vue construite.

COLUMNS ( json_table_column [, ...] )

La clause COLUMNS dĂ©finit le schĂ©ma de la vue construite. Dans cette clause, vous pouvez spĂ©cifier chaque colonne Ă  remplir avec une valeur SQL/JSON obtenue en appliquant une expression de chemin JSON au motif de ligne. json_table_column possĂšde les variantes suivantes :

name FOR ORDINALITY

Ajoute une colonne d'ordinalité qui fournit une numérotation séquentielle des lignes à partir de 1. Chaque NESTED PATH (voir ci-dessous) obtient son propre compteur pour les colonnes d'ordinalité imbriquées.

name type [FORMAT JSON [ENCODING UTF8]] [ PATH path_expression ]

InsÚre une valeur SQL/JSON obtenue en appliquant path_expression au motif de ligne, dans la ligne de sortie de la vue aprÚs l'avoir convertie au type spécifié.

La spécification de FORMAT JSON rend explicite le fait que vous attendez que la valeur soit un objet json valide. Il est uniquement pertinent de spécifier FORMAT JSON que si type est l'un des bpchar, bytea, character varying, name, json, jsonb, text, ou un domaine sur ces types.

En option, vous pouvez spécifier les clauses WRAPPER et QUOTES pour formater la sortie. Notez que la spécification de OMIT QUOTES remplace FORMAT JSON si elle est également spécifiée, car les litéraux non cités ne constituent pas des valeurs json valides.

En option, vous pouvez utiliser les clauses ON EMPTY et ON ERROR pour spécifier s'il faut remonter l'erreur ou renvoyer la valeur spécifiée lorsque le résultat de l'évaluation du chemin JSON est vide, et lorsqu'une erreur se produit pendant l'évaluation du chemin JSON ou lors de la conversion de la valeur SQL/JSON au type spécifié, respectivement. La valeur par défaut pour les deux est de renvoyer une valeur NULL.

Note

Cette clause est convertie en interne et a la mĂȘme sĂ©mantique que JSON_VALUE ou JSON_QUERY. Ce sera JSON_QUERY si le type spĂ©cifiĂ© n'est pas un type scalaire ou si l'une des clauses FORMAT JSON, WRAPPER ou QUOTES est prĂ©sente.

name type EXISTS [ PATH path_expression ]

InsÚre une valeur booléenne obtenue en appliquant path_expression au motif de ligne, dans la ligne en sortie de la vue aprÚs l'avoir convertie au type spécifié.

La valeur correspond Ă  l'application de l'expression PATH au motif de ligne renvoyant des valeurs ou non.

Le type spécifié doit avoir une conversion à partir du type boolean.

En option, vous pouvez utiliser ON ERROR pour spécifier s'il faut remonter l'erreur ou renvoyer la valeur spécifiée lorsqu'une erreur se produit pendant l'évaluation du chemin JSON ou lors de la conversion de la valeur SQL/JSON au type spécifié. La valeur par défaut est de renvoyer une valeur booléenne FALSE.

Note

Cette clause est convertie en interne et, est sémantiquement équivalent à JSON_EXISTS.

NESTED [ PATH ] path_expression [ AS json_path_name ] COLUMNS ( json_table_column [, ...] )

Extrait des valeurs SQL/JSON des niveaux imbriquĂ©s du modĂšle de ligne, gĂ©nĂšre une ou plusieurs colonnes dĂ©finies par la sous-clause COLUMNS, et insĂšre les valeurs SQL/JSON ayant Ă©tĂ© extraites dans ces colonnes. L'expression json_table_column dans la sous-clause COLUMNS utilise la mĂȘme syntaxe que dans la clause COLUMNS parente.

La syntaxe NESTED PATH est récursive, vous pouvez donc utiliser plusieurs niveaux imbriqués en spécifiant plusieurs sous-clauses NESTED PATH les unes dans les autres. Cela permet de décomposer la hiérarchie des objets et tableaux JSON en un seul appel de la fonction plutÎt que de chaßner plusieurs expressions JSON_TABLE dans une instruction SQL.

Note

Dans chaque variante de json_table_column dĂ©crite ci-dessus, si la clause PATH est omise, l'expression de chemin $.name est utilisĂ©e, oĂč name est le nom de colonne fourni.

AS json_path_name

Le json_path_name optionnel sert d'identifiant du path_expression fourni. Le nom doit ĂȘtre unique et distinct des noms de colonnes.

{ ERROR | EMPTY } ON ERROR

La clause optionnelle ON ERROR peut ĂȘtre utilisĂ©e pour spĂ©cifier comment gĂ©rer les erreurs lors de l'Ă©valuation du path_expression de niveau supĂ©rieur. Utilisez ERROR si vous souhaitez que les erreurs se gĂ©nĂšrent et EMPTY pour renvoyer une table vide, c'est-Ă -dire une table contenant 0 ligne. Notez que cette clause n'affecte pas les erreurs qui surviennent lors de l'Ă©valuation des colonnes, pour lesquelles le comportement dĂ©pend de la spĂ©cification de la clause ON ERROR pour une colonne donnĂ©e.

Examples

Dans les exemples suivants, la table ci-dessous sera utilisĂ©e avec les donnĂ©es JSON indiquĂ©es :

CREATE TABLE my_films ( js jsonb );

INSERT INTO my_films VALUES (
'{ "favorites" : [
   { "kind" : "comedy", "films" : [
     { "title" : "Bananas",
       "director" : "Woody Allen"},
     { "title" : "The Dinner Game",
       "director" : "Francis Veber" } ] },
   { "kind" : "horror", "films" : [
     { "title" : "Psycho",
       "director" : "Alfred Hitchcock" } ] },
   { "kind" : "thriller", "films" : [
     { "title" : "Vertigo",
       "director" : "Alfred Hitchcock" } ] },
   { "kind" : "drama", "films" : [
     { "title" : "Yojimbo",
       "director" : "Akira Kurosawa" } ] }
  ] }');
   

La requĂȘte suivante montre comment utiliser JSON_TABLE pour transformer les objets JSON de la table my_films en une vue contenant des colonnes pour les clĂ©s kind, title et director contenues dans le JSON original ainsi qu'une colonne d'ordinalitĂ© :

SELECT jt.* FROM
 my_films,
 JSON_TABLE (js, '$.favorites[*]' COLUMNS (
   id FOR ORDINALITY,
   kind text PATH '$.kind',
   title text PATH '$.films[*].title' WITH WRAPPER,
   director text PATH '$.films[*].director' WITH WRAPPER)) AS jt;

 id |   kind   |             title              |             director
----+----------+--------------------------------+----------------------------------
  1 | comedy   | ["Bananas", "The Dinner Game"] | ["Woody Allen", "Francis Veber"]
  2 | horror   | ["Psycho"]                     | ["Alfred Hitchcock"]
  3 | thriller | ["Vertigo"]                    | ["Alfred Hitchcock"]
  4 | drama    | ["Yojimbo"]                    | ["Akira Kurosawa"]
(4 rows)

Voici une version modifiĂ©e de la requĂȘte ci-dessus pour montrer l'utilisation des arguments PASSING dans le filtre spĂ©cifiĂ© dans l'expression de chemin JSON de niveau supĂ©rieur ainsi que les diffĂ©rentes options pour les colonnes individuelles :

SELECT jt.* FROM
 my_films,
 JSON_TABLE (js, '$.favorites[*] ? (@.films[*].director == $filter)'
   PASSING 'Alfred Hitchcock' AS filter
     COLUMNS (
     id FOR ORDINALITY,
     kind text PATH '$.kind',
     title text FORMAT JSON PATH '$.films[*].title' OMIT QUOTES,
     director text PATH '$.films[*].director' KEEP QUOTES)) AS jt;

 id |   kind   |  title  |      director
----+----------+---------+--------------------
  1 | horror   | Psycho  | "Alfred Hitchcock"
  2 | thriller | Vertigo | "Alfred Hitchcock"
(2 rows)

Voici une version modifiĂ©e de la requĂȘte ci-dessus pour montrer l'utilisation de NESTED PATH pour remplir les colonnes title et director, illustrant comment elles sont jointes aux colonnes parents id et kind :

SELECT jt.* FROM
 my_films,
 JSON_TABLE ( js, '$.favorites[*] ? (@.films[*].director == $filter)'
   PASSING 'Alfred Hitchcock' AS filter
   COLUMNS (
    id FOR ORDINALITY,
    kind text PATH '$.kind',
    NESTED PATH '$.films[*]' COLUMNS (
      title text FORMAT JSON PATH '$.title' OMIT QUOTES,
      director text PATH '$.director' KEEP QUOTES))) AS jt;

 id |   kind   |  title  |      director
----+----------+---------+--------------------
  1 | horror   | Psycho  | "Alfred Hitchcock"
  2 | thriller | Vertigo | "Alfred Hitchcock"
(2 rows)

La prochaine est la mĂȘme requĂȘte, mais cette fois ci, sans le filtre dans le chemin racine :

SELECT jt.* FROM
 my_films,
 JSON_TABLE ( js, '$.favorites[*]'
   COLUMNS (
    id FOR ORDINALITY,
    kind text PATH '$.kind',
    NESTED PATH '$.films[*]' COLUMNS (
      title text FORMAT JSON PATH '$.title' OMIT QUOTES,
      director text PATH '$.director' KEEP QUOTES))) AS jt;

 id |   kind   |      title      |      director
----+----------+-----------------+--------------------
  1 | comedy   | Bananas         | "Woody Allen"
  1 | comedy   | The Dinner Game | "Francis Veber"
  2 | horror   | Psycho          | "Alfred Hitchcock"
  3 | thriller | Vertigo         | "Alfred Hitchcock"
  4 | drama    | Yojimbo         | "Akira Kurosawa"
(5 rows)

Voici une autre requĂȘte utilisant un objet JSON diffĂ©rent comme entrĂ©e. Elle montre l'union "sibling join" (frĂšres et sƓurs) entre les chemins NESTED $.movies[*] et $.books[*] et Ă©galement l'utilisation de la colonne FOR ORDINALITY aux niveaux NESTED (colonnes movie_id, book_id et author_id) :

SELECT * FROM JSON_TABLE (
'{"favorites":
    [{"movies":
      [{"name": "One", "director": "John Doe"},
       {"name": "Two", "director": "Don Joe"}],
     "books":
      [{"name": "Mystery", "authors": [{"name": "Brown Dan"}]},
       {"name": "Wonder", "authors": [{"name": "Jun Murakami"}, {"name":"Craig Doe"}]}]
}]}'::json, '$.favorites[*]'
COLUMNS (
  user_id FOR ORDINALITY,
  NESTED '$.movies[*]'
    COLUMNS (
    movie_id FOR ORDINALITY,
    mname text PATH '$.name',
    director text),
  NESTED '$.books[*]'
    COLUMNS (
      book_id FOR ORDINALITY,
      bname text PATH '$.name',
      NESTED '$.authors[*]'
        COLUMNS (
          author_id FOR ORDINALITY,
          author_name text PATH '$.name'))));

 user_id | movie_id | mname | director | book_id |  bname  | author_id | author_name
---------+----------+-------+----------+---------+---------+-----------+--------------
       1 |        1 | One   | John Doe |         |         |           |
       1 |        2 | Two   | Don Joe  |         |         |           |
       1 |          |       |          |       1 | Mystery |         1 | Brown Dan
       1 |          |       |          |       2 | Wonder  |         1 | Jun Murakami
       1 |          |       |          |       2 | Wonder  |         2 | Craig Doe
(5 rows)