表9.42「jsonとjsonb演算子」に2つのJSONデータ型(8.14. JSONデータ型を参照)で使用可能な演算子を示します。
表9.42 jsonとjsonb演算子
| 演算子 | 右オペランド型 | 説明 | 例 | 例の結果 |
|---|---|---|---|---|
-> | int | JSON配列要素を取得(添字はゼロから、負数なら後ろから数える) | '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2 | {"c":"baz"} |
-> | text | キーに依るJSONオブジェクトフィールド取得 | '{"a": {"b":"foo"}}'::json->'a' | {"b":"foo"} |
->> | int | JSON 配列要素をtextとして取得 | '[1,2,3]'::json->>2 | 3 |
->> | text | JSON オブジェクトフィールドをtextとして取得 | '{"a":1,"b":2}'::json->>'b' | 2 |
#> | text[] | 指定されたパスにあるJSONオブジェクトを取得 | '{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}' | {"c": "foo"} |
#>> | text[] | 指定されたパスにあるJSONオブジェクトをtextとして取得 | '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}' | 3 |
jsonとjsonb型の両方に対して、以上の演算子の対応するものがあります。
フィールド/要素/パス抽出演算子は左辺の入力と同じ型(jsonまたはjsonb)を返します。
ただし、textを返すと明示してあるものは、値をテキストに変換して返します。
JSON入力が要求と一致する正しい構造をしていなければ、フィールド/要素/パス抽出演算子は失敗するのではなくNULLを返します。例えばそのような要素が存在しない場合です。
JSON配列の添字を整数で受け取り、フィールド、要素、パスを返す演算子はすべて、配列の終わりから数える負の添字をサポートします。
表9.1「比較演算子」に示されている標準の比較演算子がjsonbで利用可能ですが、jsonではそうではありません。
それらは8.14.4. jsonb インデックスで概略を述べたB-tree演算子の順序規則に従います。
ほかにjsonbだけで利用可能な演算子もいくつか存在します。
それらを表9.43「追加jsonb演算子」に示します。
これらのうち多くの演算子はjsonb演算子クラスでインデックス付けすることが可能です。
jsonbの包含と存在の意味に関する完全な記述は8.14.3. jsonb型用包含演算子と存在演算子を参照してください。
8.14.4. jsonb インデックスには、jsonbデータを効率的にインデックス付けするためにこれらの演算子をどのように利用できるかについて書いてあります。
表9.43 追加jsonb演算子
| 演算子 | 右オペランド型 | 説明 | 例 |
|---|---|---|---|
@> | jsonb | 左のJSON値はトップレベルにおいて右のJSONパスまたは値を包含するか | '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb |
<@ | jsonb | 左のJSONパスまたは値は右のJSON値にトップレベルで包含されるか | '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb |
? | text | 文字列はJSON値のトップレベルのキーとして存在するか | '{"a":1, "b":2}'::jsonb ? 'b' |
?| | text[] | 配列の文字列のいずれかがトップレベルのキーとして存在するか。 | '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c'] |
?& | text[] | 配列の文字列のすべてがトップレベルのキーとして存在するか。 | '["a", "b"]'::jsonb ?& array['a', 'b'] |
|| | jsonb | 2つのjsonb値を結合して、新しいjsonb値を作る | '["a", "b"]'::jsonb || '["c", "d"]'::jsonb |
- | text | 左のオペランドからキー/値のペア、あるいは文字列要素を削除する。 キー/値のペアはキーの値に基づいてマッチされる。 | '{"a": "b"}'::jsonb - 'a' |
- | integer | 指定した添字の配列要素を削除する(負数の場合は後ろから数えます)。 トップレベルのコンテナが配列でないときはエラーが発生する。 | '["a", "b"]'::jsonb - 1 |
#- | text[] | 指定したパスのフィールドまたは要素を削除する(JSON配列では、負数は後ろから数えます) | '["a", {"b":1}]'::jsonb #- '{1,b}' |
||演算子は、両オペランドのトップレベルで要素を結合します。
再帰的には作用しません。
例えば、両方のオペランドが同じキーフィールド名のオブジェクトの場合、そのフィールドの値は、単に右側のオペランドの値になります。
表9.44「JSON作成関数」に、JSON値およびjsonb値を作成するために利用可能な関数を示します。
(row_to_json関数およびarray_to_json関数と同等なjsonbの関数はありません。
しかし、to_jsonbを使えば、これらの関数と同じ機能を提供できるでしょう。)
表9.44 JSON作成関数
| 関数 | 説明 | 例 | 例の結果 |
|---|---|---|---|
| jsonあるいはjsonbとして値を返す。
配列と複合型は(再帰的に)配列とオブジェクトに変換される。
あるいは、その型からjsonにキャストがあれば、キャスト関数が変換のために用いられる。
そうでなければ、スカラ値が生成される。
数値、論理値、またはNULL値以外のスカラ型に対しては、有効なjson値あるいはjsonb値となる形式の文字列表現が使用される。
| to_json('Fred said "Hi."'::text) | "Fred said \"Hi.\"" |
array_to_json(anyarray [, pretty_bool])
| 配列をJSON配列として返す。
PostgreSQLの多次元配列はJSON配列の配列となる。
pretty_boolが真の場合、次元数-1の要素の間に改行が加えられる。
| array_to_json('{{1,5},{99,100}}'::int[]) | [[1,5],[99,100]] |
row_to_json(record [, pretty_bool])
| 行をJSONオブジェクトとして返す。
pretty_boolが真の場合、レベル-1の要素の間に改行が加えられる。
| row_to_json(row(1,'foo')) | {"f1":1,"f2":"foo"} |
| 異なる型から構成される可能性のあるJSON配列をvariadic引数リストから作成。 | json_build_array(1,2,'3',4,5) | [1, 2, "3", 4, 5] |
| variadic引数リストからJSONオブジェクトを作成。 慣例により引数リストはキーと値が交互に並んだもの。 | json_build_object('foo',1,'bar',2) | {"foo": 1, "bar": 2} |
| テキスト配列からJSONオブジェクトを作成。 配列は、偶数個の要素からなる1次元(キー/値の対が交互に並んでいるものと扱われる))あるいは内側の配列が2つの要素を持つ2次元(2つの要素がキー/値の対として扱われる)のいずれかでなければならない。 |
| {"a": "1", "b": "def", "c": "3.5"} |
| この形のjson_objectは2つの別々の配列からキーと値の対を取る。
他の点ではすべて、引数1つの形と同じ。
| json_object('{a, b}', '{1,2}') | {"a": "1", "b": "2"} |
array_to_jsonとrow_to_jsonは表示を整えるオプションを提供する以外はto_jsonと同様の振舞いをします。
同様にto_jsonに書かれた振舞いはJSON作成関数により変換された個々の値に適用されます。
hstore拡張はhstoreからjsonへのキャストを含みます。従って、JSON作成関数で変換されたhstore値は元の文字列値ではなくJSONオブジェクトとして示されます。
表9.45「JSON処理関数」にjsonとjsonb値を処理するのに使える関数を示します。
表9.45 JSON処理関数
| 関数 | 戻り値型 | 説明 | 例 | 例の結果 |
|---|---|---|---|---|
| int | JSON配列の最も外側の要素の数を返す。 | json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') | 5 |
|
| JSONオブジェクトの最も外側をkey/valueの組み合わせに拡張する。 | select * from json_each('{"a":"foo", "b":"bar"}') | key | value -----+------- a | "foo" b | "bar" |
| setof key text, value text | JSONオブジェクトの最も外側をkey/valueの組み合わせに拡張する。返り値は型text。
| select * from json_each_text('{"a":"foo", "b":"bar"}') | key | value -----+------- a | foo b | bar |
|
| path_elemsで示されたJSONオブジェクトを返す(#>と同じ)。
| json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4') | {"f5":99,"f6":"foo"} |
| text | path_elemsで示されたJSONオブジェクトをtextとして返す(#>>演算子と同じ)。
| json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6') | foo |
| setof text | 最も外側のJSONオブジェクトの中のキーの集合を返す。 | json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') | json_object_keys ------------------ f1 f2 |
| anyelement | from_json内のオブジェクトを行をbaseで定義されたレコード型に一致する列に拡張する(以下の注意書きを参照)。
| select * from json_populate_record(null::myrowtype, '{"a":1,"b":2}') | a | b ---+--- 1 | 2 |
| setof anyelement | from_jsonにおけるオブジェクトの最も外側の配列をbaseで定義されたレコード型に一致する列を持つ行の集合に展開する(以下の注意書き参照)。
| select * from json_populate_recordset(null::myrowtype, '[{"a":1,"b":2},{"a":3,"b":4}]') | a | b ---+--- 1 | 2 3 | 4 |
|
| JSON配列をJSON値の集合に展開する。 | select * from json_array_elements('[1,true, [2,false]]') | value ----------- 1 true [2,false] |
| setof text | JSON配列をtext値の集合に展開する。
| select * from json_array_elements_text('["foo", "bar"]') | value ----------- foo bar |
| text | 最も外側のJSON値の型をテキスト文字列として返す。
取りうる型はobject、 array、 string、 number、boolean、nullである。
| json_typeof('-123.4') | number |
| record | JSONオブジェクトから任意のレコードを作成する(下記の注釈を参照)。
recordを返す関数すべてと同様、呼び出し側がAS句でレコードの構造を明示的に決める必要がある。
| select * from json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}') as x(a int, b text, d text) | a | b | d ---+---------+--- 1 | [1,2,3] | |
| setof record | オブジェクトの配列のJSONから任意のレコードの集合を作成する(下記の注釈を参照)。
recordを返す関数すべてと同様、呼び出し側がAS句でレコードの構造を明示的に決める必要がある。
| select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text); | a | b ---+----- 1 | foo 2 | |
|
| NULL値を持つオブジェクトフィールドを削除したfrom_jsonを返す。
他のNULL値はそのまま残る。
| json_strip_nulls('[{"f1":1,"f2":null},2,null,3]') | [{"f1":1},2,null,3] |
|
| pathで指定した部分をnew_valueで置換、
あるいはcreate_missingが真(デフォルトはtrue)でpathで指定した項目が存在しないならnew_valueを追加して、
targetを返す。
パスの位置についての演算子について、pathの中にある負の整数はJSON配列の終わりから数える。
|
|
|
|
|
| new_valueを挿入してtargetを返す。
pathで指定したtargetの部分がJSONB配列内にある場合は、new_valueはtargetの前に挿入されるか、あるいは、insert_afterが真であれば(デフォルトはfalse)、後に挿入される。
pathで指定したtargetの部分がJSONBオブジェクト内にある場合は、new_valueはtargetが存在しない場合にのみ挿入される。
pathについての演算子について言うと、new_value内の負の整数はJSON配列の終わりから数える。
|
|
|
|
| from_jsonをインデントしたJSON文字列にして返す。
| jsonb_pretty('[{"f1":1,"f2":null},2,null,3]') | [
{
"f1": 1,
"f2": null
},
2,
null,
3
]
|
これらの多くの関数や演算子は、JSON文字列のUnicodeのエスケープを適切な一文字に変換します。
これは入力がjsonb型であれば、変換は既に行なわれていますので、重要な問題ではありません。しかし、jsonの入力に対しては、8.14. JSONデータ型で言及したようにこれはエラーを発生させる結果になるかもしれません.
json_populate_record、json_populate_recordset、json_to_recordおよびjson_to_recordsetにおけるJSONからの型強制は「最善努力」であり、ある型では望んだ結果にならないかもしれません。
JSONキーは対象の行の型の中の同一の列の名前と一致します。
対象の行の型に現れないJSONフィールドは出力から省略され、JSONフィールドに一致しない対象の列は単にNULLになります。
jsonb_setおよびjsonb_insertのpathパラメータは、最後の項目を除き、すべての項目がtarget内に存在しなければなりません。
create_missingが偽ならなら、jsonb_setのpathパラメータのすべての項目が存在しなければなりません。
これらの条件が満たされなければ、targetが変更されずに返されます。
パスの最後の要素がオブジェクトのキーの場合、それが存在しなければ作成されて、新しい値が与えられます。
パスの最後の項目が配列の添字の場合、それが正ならセットすべき項目は左から数えられ、負なら右から数えられます(-1は最も右側の要素を指す、という具合です)。
項目が[-array_length .. array_length -1]の範囲外にあり、かつcreate_missingが真なら、新しい値が配列の先頭(項目が負数のとき)あるいは配列の終わり(項目が正数のとき)に追加されます。
json_typeofのnull戻り値をSQLのNULLと混同してはいけません。
json_typeof('null'::json)を呼び出すとnullが返りますが、json_typeof(NULL::json)を呼び出すとSQLのNULLが返ります。
json_strip_nullsの引数で、オブジェクト内にフィールド名が重複しているものがある場合、それが発生している順序によって、結果は意味的にやや異なるものになることがあります。
jsonb値はオブジェクトのフィールド名が重複することがないので、jsonb_strip_nullsにはこのような問題はありません。
レコードの値をJSONに集約するjson_agg集約関数、値の対をJSONオブジェクトに集約するjson_object_agg集約関数、およびそれらのjsonb版のjsonb_aggとjsonb_object_aggについては9.20. 集約関数を参照して下さい。