PolarDB for Oracle では、JSON データの照会および操作に使用できる包括的な演算子および関数セットを備えた json および jsonb データの型がサポートされています。このページでは、以下の内容について説明します。
json および jsonb の演算子
以下の演算子は、json および jsonb の値の両方に適用できます。標準比較演算子(=、<、> など)は、jsonb のみで利用可能であり、json にはありません。これらの比較演算子は、B ツリー順序規則に従います。
json および jsonb で共用される演算子
| 演算子 | 説明 | 例 | 結果 |
|---|---|---|---|
json -> integer → json<br>jsonb -> integer → jsonb | JSON 配列の n 番目の要素を抽出します。配列要素のインデックスは 0 から始まり、負の整数は末尾からカウントされます。 | '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> 2<br>'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> -3 | {"c":"baz"}<br>{"a":"foo"} |
json -> text → json<br>jsonb -> text → jsonb | キーを指定して JSON オブジェクトのフィールドを抽出します。 | '{"a": {"b":"foo"}}'::json -> 'a' | {"b":"foo"} |
json ->> integer → text<br>jsonb ->> integer → text | JSON 配列の n 番目の要素を text 型として抽出します。 | '[1,2,3]'::json ->> 2 | 3 |
json ->> text → text<br>jsonb ->> text → text | キーを指定して JSON オブジェクトのフィールドを text 型として抽出します。 | '{"a":1,"b":2}'::json ->> 'b' | 2 |
json #> text[] → json<br>jsonb #> text[] → jsonb | 指定されたパスにある JSON サブオブジェクトを抽出します。パス要素には、フィールドキーまたは配列インデックスを指定できます。 | '{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}' | "bar" |
json #>> text[] → text<br>jsonb #>> text[] → text | 指定されたパスにある JSON サブオブジェクトを text 型として抽出します。 | '{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}' | bar |
フィールド、要素、およびパス抽出演算子は、JSON 入力が要求された構造と一致しない場合(たとえば、キーまたは配列要素が存在しない場合など)にエラーを発生させるのではなく、NULL を返します。
jsonb 専用の追加演算子
| オペレーター | 説明 | 例 | 結果 | ||
|---|---|---|---|---|---|
jsonb @> jsonb → boolean | 最初の JSON 値に 2 番目の JSON 値が含まれていますか? | '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb | t | ||
jsonb <@ jsonb → boolean | 最初の JSON 値は 2 番目の JSON 値に含まれていますか? | '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb | t | ||
jsonb ? text → boolean | テキスト文字列がトップレベルキーまたは配列要素として存在しますか? | '{"a":1, "b":2}'::jsonb ? 'b' | t | ||
| `jsonb ? | text[] → boolean` | テキスト配列内のいずれかの文字列がトップレベルキーまたは配列要素として存在しますか? | `'{"a":1, "b":2, "c":3}'::jsonb ? | array['b', 'd']` | t |
jsonb ?& text[] → boolean | テキスト配列内のすべての文字列がトップレベルキーまたは配列要素として存在しますか? | '["a", "b", "c"]'::jsonb ?& array['a', 'b'] | t | ||
jsonb || jsonb → jsonb | 2 つの jsonb 値を連結します。2 つの配列は、両方の入力からのすべての要素を含む配列を生成します。2 つのオブジェクトは、キーの結合を持つオブジェクトを生成します。重複するキーの場合、2 番目のオブジェクトの値が優先されます。配列以外の入力は、連結前に単一要素配列に変換されます。トップレベル構造のみがマージされます。連結は再帰的ではありません。配列を別の配列内に単一のエントリとして追加するには、追加の配列レイヤーでラップします。例: '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) → [1, 2, [3, 4]] | '["a", "b"]'::jsonb || '["a", "d"]'::jsonb'{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb'[1, 2]'::jsonb || '3'::jsonb'{"a": "b"}'::jsonb || '42'::jsonb | ["a", "b", "a", "d"]{"a": "b", "c": "d"}[1, 2, 3][{"a": "b"}, 42] | ||
jsonb - text → jsonb | JSON オブジェクトからキー (およびその値) を、または JSON 配列からすべての一致する文字列値を削除します。 | '{"a": "b", "c": "d"}'::jsonb - 'a' | {"c": "d"} | ||
jsonb - text[] → jsonb | 左オペランドからすべての一致するキーまたは配列要素を削除します。 | '{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[] | {} | ||
jsonb - integer → jsonb | 指定されたインデックスの配列要素を削除します。負の整数は末尾から数えます。JSON 値が配列でない場合、エラーをスローします。 | '["a", "b"]'::jsonb - 1 | ["a"] | ||
jsonb #- text[] → jsonb | 指定されたパスのフィールドまたは配列要素を削除します。パス要素はフィールドキーまたは配列インデックスにできます。 | '["a", {"b":1}]'::jsonb #- '{1,b}' | ["a", {}] | ||
jsonb @? jsonpath → boolean | 指定された JSON 値に対して JSON パスは任意の項目を返しますか? | '{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' | t | ||
jsonb @@ jsonpath → boolean | JSON パス述語チェックの結果を返します。結果の最初の項目のみが評価されます。結果がブール値でない場合、NULL を返します。 | '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' | t |
@?および@@演算子は、以下のエラーを抑制します:オブジェクトのフィールドまたは配列要素の欠落、予期しない JSON アイテムの型、日時および数値に関するエラー。この動作は、構造が異なる JSON ドキュメントのコレクションを照会する際に有用です。
JSON 作成関数
以下の関数は、SQL データから json および jsonb の値を構築します。
to_json および to_jsonb
to_json ( anyelement ) → json
to_jsonb ( anyelement ) → jsonb任意の SQL 値を json または jsonb に変換します。配列および複合型は、JSON 配列およびオブジェクトに再帰的に変換されます。SQL 型から json へのキャストが存在する場合は、そのキャスト関数が使用されます。それ以外の場合、スカラー値は適切な形式(エスケープを含む)で JSON 文字列、ブール値、数値、または null として表現されます。
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
array_to_json ( anyarray [, boolean ] ) → jsonSQL 配列を JSON 配列に変換します。省略可能なブール値パラメーターが true の場合、最上位レベルの配列要素間に改行が挿入されます。
array_to_json('{{1,5},{99,100}}'::int[])
-- → [[1,5],[99,100]]row_to_json
row_to_json ( record [, boolean ] ) → jsonSQL 複合値を JSON オブジェクトに変換します。省略可能なブール値パラメーターが true の場合、最上位レベルの要素間に改行が挿入されます。
row_to_json(row(1,'foo'))
-- → {"f1":1,"f2":"foo"}json_build_array および jsonb_build_array
json_build_array ( VARIADIC "any" ) → json
jsonb_build_array ( VARIADIC "any" ) → jsonb可変長引数リストから、異種型の JSON 配列を構築します。各引数は to_json または to_jsonb を使用して変換されます。
json_build_array(1, 2, 'foo', 4, 5)
-- → [1, 2, "foo", 4, 5]json_build_object および jsonb_build_object
json_build_object ( VARIADIC "any" ) → json
jsonb_build_object ( VARIADIC "any" ) → jsonb可変長引数リスト(交互にキーと値を指定)から JSON オブジェクトを構築します。キー引数は text 型に強制変換され、値は to_json または to_jsonb を使用して変換されます。
json_build_object('foo', 1, 2, row(3,'bar'))
-- → {"foo" : 1, "2" : {"f1":3,"f2":"bar"}}json_object および jsonb_object
json_object ( text[] ) → json
jsonb_object ( text[] ) → jsonbテキスト配列から JSON オブジェクトを構築します。配列は、偶数個のメンバーを持つ 1 次元配列(交互にキー/値ペアとして扱われる)または、各内側配列が正確に 2 つの要素を持つ 2 次元配列のいずれかである必要があります。すべての値は 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"}2 つの引数を取る形式では、別々のテキスト配列からキーと値を取得します。
json_object ( keys text[], values text[] ) → json
jsonb_object ( keys text[], values text[] ) → jsonbjson_object('{a,b}', '{1,2}')
-- → {"a": "1", "b": "2"}拡張機能がその型からjsonへのキャスト(たとえば、hstore拡張機能)を提供する場合、これらの作成関数によって変換された値は、プリミティブな文字列ではなく、そのキャストを使用します。
JSON 処理関数
以下の関数は、json および jsonb の値を照会および操作します。
JSON の展開および照会
json_array_elements および jsonb_array_elements
json_array_elements ( json ) → setof json
jsonb_array_elements ( jsonb ) → setof jsonb最上位レベルの JSON 配列を JSON 値のセットに展開します。
select * from json_array_elements('[1,true, [2,false]]');
-- value
-- -----------
-- 1
-- true
-- [2,false]json_array_elements_text および jsonb_array_elements_text
json_array_elements_text ( json ) → setof text
jsonb_array_elements_text ( jsonb ) → setof text最上位レベルの JSON 配列を text 値のセットに展開します。
select * from json_array_elements_text('["foo", "bar"]');
-- value
-- -----------
-- foo
-- barjson_array_length および jsonb_array_length
json_array_length ( json ) → integer
jsonb_array_length ( jsonb ) → integer最上位レベルの JSON 配列の要素数を返します。
json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')
-- → 5json_each および jsonb_each
json_each ( json ) → setof record ( key text, value json )
jsonb_each ( jsonb ) → setof record ( key text, value jsonb )最上位レベルの JSON オブジェクトをキー/値ペアのセットに展開します。
select * from json_each('{"a":"foo", "b":"bar"}');
-- key | value
-- -----+-------
-- a | "foo"
-- b | "bar"json_each_text および jsonb_each_text
json_each_text ( json ) → setof record ( key text, value text )
jsonb_each_text ( jsonb ) → setof record ( key text, value text )最上位レベルの JSON オブジェクトをキー/値ペアのセットに展開し、値を text 型として返します。
select * from json_each_text('{"a":"foo", "b":"bar"}');
-- key | value
-- -----+-------
-- a | foo
-- b | barjson_object_keys および jsonb_object_keys
json_object_keys ( json ) → setof text
jsonb_object_keys ( jsonb ) → setof text最上位レベルの JSON オブジェクトのキーのセットを返します。
select * from json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}');
-- json_object_keys
-- ------------------
-- f1
-- f2サブオブジェクトの抽出
json_extract_path および jsonb_extract_path
json_extract_path ( from_json json, VARIADIC path_elems text[] ) → json
jsonb_extract_path ( from_json jsonb, VARIADIC path_elems text[] ) → jsonb指定されたパスにある JSON サブオブジェクトを抽出します。#> 演算子と同等ですが、パスを可変長リストとして記述することで、特定のケースではより便利になります。
json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')
-- → "foo"json_extract_path_text および jsonb_extract_path_text
json_extract_path_text ( from_json json, VARIADIC path_elems text[] ) → text
jsonb_extract_path_text ( from_json jsonb, VARIADIC path_elems text[] ) → text指定されたパスにある JSON サブオブジェクトを text 型として抽出します。#>> 演算子と同等です。
json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')
-- → fooJSON からの複合型へのポピュレート
json_populate_record および jsonb_populate_record
json_populate_record ( base anyelement, from_json json ) → anyelement
jsonb_populate_record ( base anyelement, from_json jsonb ) → anyelement最上位レベルの JSON オブジェクトを、base の複合型に一致する行に展開します。出力カラム名と一致するフィールド名は対応するカラムに挿入され、一致しないフィールドは無視されます。base が NULL の場合、一致しないカラムは null で埋められます。それ以外の場合、一致しないカラムは base の値を保持します。
以下の型変換ルールが順に適用されます。
JSON の null は、すべての場合において SQL の NULL に変換されます。
出力カラムが
jsonまたはjsonb型の場合、JSON 値はそのまま再現されます。出力カラムが複合型(行)であり、JSON 値が JSON オブジェクトの場合、フィールドは再帰的に変換されます。
出力カラムが配列型であり、JSON 値が JSON 配列の場合、要素は再帰的に変換されます。
JSON 値が文字列の場合、その内容はカラムのデータ型の入力変換関数に渡されます。
それ以外の場合、JSON 値のテキスト表現が入力変換関数に渡されます。
json_populate_record を FROM 句で使用すると、重複した関数呼び出しをせずにすべての抽出カラムを利用できます。
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")json_populate_recordset および jsonb_populate_recordset
json_populate_recordset ( base anyelement, from_json json ) → setof anyelement
jsonb_populate_recordset ( base anyelement, from_json jsonb ) → setof anyelement最上位レベルの JSON 配列(オブジェクトの配列)を、base の複合型に一致する行のセットに展開します。各要素は、json_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 | 4json_to_record および jsonb_to_record
json_to_record ( json ) → record
jsonb_to_record ( jsonb ) → record最上位レベルの JSON オブジェクトを、AS 句で定義された複合型の行に展開します。呼び出し元のクエリでは、AS 句でレコード構造を明示的に定義する必要があります。一致しないカラムは常に 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 および jsonb_to_recordset
json_to_recordset ( json ) → setof record
jsonb_to_recordset ( jsonb ) → setof record最上位レベルの JSON 配列(オブジェクトの配列)を、AS 句で定義された複合型の行のセットに展開します。各要素は、json_to_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 |JSON 値の変更
jsonb_set
jsonb_set ( target jsonb, path text[], new_value jsonb [, create_if_missing boolean ] ) → jsonbtarget の path にある項目を new_value で置き換えます。create_if_missing が true(デフォルト)であり、path にある項目が存在しない場合、代わりに new_value が挿入されます。パスの前のすべてのステップが存在する必要があります。そうでない場合は、target が変更されずに返されます。
path 内の負の整数は、JSON 配列の末尾からカウントされます。create_if_missing が true であり、最後のパスステップが範囲外の配列インデックスである場合、新しい値は配列の先頭(負のインデックスの場合)または末尾(正のインデックスの場合)に追加されます。
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
jsonb_set_lax ( target jsonb, path text[], new_value jsonb [, create_if_missing boolean [, null_value_treatment text ]] ) → jsonbnew_value が NULL でない場合、jsonb_set と同一の動作をします。new_value が NULL の場合、null_value_treatment に応じて動作が異なります。
| 値 | 動作 |
|---|---|
'raise_exception' | エラーをスローします |
'use_json_null' | ターゲットを JSON の null に設定します(デフォルト) |
'delete_key' | パスにあるキーを削除します |
'return_target' | target を変更せずに返します |
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
jsonb_insert ( target jsonb, path text[], new_value jsonb [, insert_after boolean ] ) → jsonbtarget の new_value を path に挿入します。配列要素の場合、new_value は insert_after が false(デフォルト)の場合はターゲット要素の前に、true の場合は後に挿入されます。オブジェクトフィールドの場合、キーが既に存在しない場合にのみ new_value が挿入されます。パスの前のすべてのステップが存在する必要があります。そうでない場合は、target が変更されずに返されます。
path 内の負の整数は、JSON 配列の末尾からカウントされます。範囲外の配列インデックスは、配列の先頭(負のインデックスの場合)または末尾(正のインデックスの場合)に値を追加します。
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 および jsonb_strip_nulls
json_strip_nulls ( json ) → json
jsonb_strip_nulls ( jsonb ) → jsonb指定された JSON 値から、null 値を持つすべてのオブジェクトフィールドを再帰的に削除します。null 値がオブジェクトフィールドでない場合(たとえば、null の配列要素など)は変更されません。
json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]')
-- → [{"f1":1},2,null,3]jsonb_pretty
jsonb_pretty ( jsonb ) → text指定された JSON 値を、インデント付きの見やすいテキスト形式に変換します。
jsonb_pretty('[{"f1":1,"f2":null}, 2]')
-- → [
-- {
-- "f1": 1,
-- "f2": null
-- },
-- 2
-- ]json_typeof および jsonb_typeof
json_typeof ( json ) → text
jsonb_typeof ( jsonb ) → text最上位レベルの JSON 値の型をテキスト文字列として返します。可能な型は、object、array、string、number、boolean、および null です。
nullの結果は、JSON の値 null を反映しており、SQL の NULL ではありません。SQL の NULL 入力は、文字列'null'ではなく、SQL の NULL 結果を返します。
json_typeof('-123.4') -- → number
json_typeof('null'::json) -- → null
json_typeof(NULL::json) IS NULL -- → t集約関数
json_agg は、レコード値を JSON 配列に集約します。json_object_agg は、値のペアを JSON オブジェクトに集約します。jsonb 版の関数 — jsonb_agg および jsonb_object_agg — は jsonb の出力を生成します。
json_agg ( anyelement ) → json
jsonb_agg ( anyelement ) → jsonb
json_object_agg ( "any", "any" ) → json
jsonb_object_agg ( "any", "any" ) → jsonbJSON パス関数
以下の関数は、jsonb 値に対して JSON パス式を評価します。
このグループのすべての関数は、同じ省略可能なパラメーターを受け入れます。
vars— フィールドが名前付き値を提供する JSON オブジェクトで、jsonpath式に代入されますsilent—trueの場合、@?および@@演算子と同じエラーが抑制されます
jsonb_path_exists
jsonb_path_exists ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → booleanJSON パスが指定された JSON 値に対して何らかの項目を返すかどうかを確認します。
jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}')
-- → tjsonb_path_match
jsonb_path_match ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → booleanJSON パス述語チェックの結果を返します。結果の最初の項目のみが評価されます。結果がブール値でない場合は NULL を返します。
jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2, "max":4}')
-- → tjsonb_path_query
jsonb_path_query ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → setof jsonbJSON パスが指定された JSON 値に対して返すすべての JSON アイテムを返します。
select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}');
-- jsonb_path_query
-- ------------------
-- 2
-- 3
-- 4jsonb_path_query_array
jsonb_path_query_array ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonbJSON パスが返すすべての JSON アイテムを JSON 配列として返します。
jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}')
-- → [2, 3, 4]jsonb_path_query_first
jsonb_path_query_first ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonbJSON パスが返す最初の JSON アイテムを返します。結果がない場合は NULL を返します。
jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}')
-- → 2タイムゾーン対応のバリエーション
jsonb_path_exists_tz、jsonb_path_match_tz、jsonb_path_query_tz、jsonb_path_query_array_tz、および jsonb_path_query_first_tz の各関数は、上記の対応する関数と同一の動作をしますが、タイムゾーン対応の変換を必要とする日時値の比較をサポートします。
これらの関数は現在の TimeZone 設定に依存するため、stable としてマークされており、インデックス内で使用できません。_tz が付かないバリアントは immutable であり、インデックス内で使用できますが、タイムゾーン依存の比較を要求された場合にエラーをスローします。
jsonb_path_exists_tz('["2015-08-01 12:00:00 -05"]', '$[*] ? (@.datetime() < "2015-08-02".datetime())')
-- → tSQL/JSON パス言語
SQL/JSON パス言語は、XML に対する XPath 式と同様に、JSON データからどの項目を取得するかを指定します。PolarDB では、パス式は jsonpath データ型として実装されています。
JSON 照会関数および演算子は、パス式をパスエンジンに渡して評価します。式が照会対象の JSON データと一致する場合、対応する JSON アイテムまたはアイテムのセットが返されます。パス式はデフォルトで左から右に評価されますが、括弧を使用して演算の順序を変更できます。
パス式による JSON の走査
$ 変数を使用して、照会対象の JSON 値(コンテキストアイテム)を参照します。$ の後に 1 つ以上のアクセサ演算子を続けて、JSON 構造を走査します。
たとえば、以下の GPS トレーカーのデータがあるとします。
{
"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
}
]
}
}.key アクセサを使用して、JSON オブジェクトを下方向に走査します。
$.track.segments[*] を使用して、配列のすべての要素を取得します。
$.track.segments[*].location数値添字を使用して、特定の要素にアクセスします(JSON 配列のインデックスは 0 から始まります)。
$.track.segments[0].locationパスステップの結果を処理するために、メソッド呼び出し(ドットで始まる)を追加します。
$.track.segments.size()フィルター式
フィルター式は、パスステップの結果を条件を満たす項目のみに絞り込みます。フィルターは、それが適用されるパスステップの直後に記述します。
? (condition)SQL/JSON では 3 値論理が使用されます。条件は true、false、または unknown のいずれかに評価されます。フィルターが true を返す項目のみが、以降のパスステップに含まれます。is unknown 述語を使用して、unknown 値をテストできます。
フィルター内では、@ はフィルター対象の値(先行するパスステップの結果)を参照します。
GPS トレーカーのデータを使用した例:
心拍数(HR)が 130 を超える値をすべて取得します。
$.track.segments[*].HR ? (@ > 130)心拍数(HR)が 130 を超えるセグメントの開始時刻を取得します(フィルターは HR 値ではなくセグメントに適用されます)。
$.track.segments[*] ? (@.HR > 130)."start time"関連する座標と高い心拍数を持つセグメントを選択するために、複数のフィルターをチェーンします。
$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"異なるネストレベルでフィルターを適用します — 最初に座標でセグメントをフィルターし、次に高い心拍数の値を返します。
$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)ネストされたフィルター式を使用して、高い心拍数の値を持つセグメントが存在する場合にのみトラックサイズを返します。
$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()Strict モードおよび Lax モード
パス式が実際の JSON 構造と一致しない場合、構造エラーが発生します。SQL/JSON パス式では、構造エラーを 2 つのモードで処理します。
Lax(デフォルト): パスエンジンは、照会対象のデータを指定されたパスに自動的に適合させます。残りの構造エラーは抑制され、空の SQL/JSON シーケンスに変換されます。比較演算子はオペランドを自動的にアンラップするため、SQL/JSON 配列を直接比較できます。サイズが 1 の配列は、その唯一の要素と等しいと見なされます。パスに
type()またはsize()メソッドが含まれている場合、または JSON データにネストされた配列が含まれている場合(最上位の配列のみがアンラップされます)、自動アンラップは適用されません。Strict: 構造エラーが発生した場合、エラーがスローされます。
GPS トレーカーのデータを lax モードで使用すると、明示的な配列アンラップを省略できます。
lax $.track.segments.locationstrict モードでは、配列を明示的にアンラップする必要があります。
strict $.track.segments[*].locationSQL/JSON 標準からの逸脱
PolarDB の実装は、SQL/JSON 標準から以下の 2 つの点で異なります。
パス式は、標準ではフィルター内でのみ許可される述語であっても、ブール値述語となることができます。これは
@@演算子で必要です。たとえば、以下のjsonpath式は有効です。$.track.segments[*].HR < 70like_regexフィルターにおける正規表現パターンの解釈に、わずかな違いがあります。
SQL/JSON パス演算子およびメソッド
すべての jsonpath 演算子およびメソッドを以下に示します。単項演算子およびメソッドは、先行するパスステップからの複数の値に適用できます。二項演算子(加算など)は、単一の値にのみ適用されます。
| 演算子/メソッド | 戻り値 | 説明 | 例 | 結果 |
|---|---|---|---|---|
number + number | number | 加算 | jsonb_path_query('[2]', '$[0] + 3') | 5 |
+ number | number | 単項プラス(ノーオペレーション);複数の値に対して反復処理可能 | jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') | [2, 3, 4] |
number - number | number | 減算 | jsonb_path_query('[2]', '7 - $[0]') | 5 |
- number | number | 符号反転;複数の値に対して反復処理可能 | jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') | [-2, -3, -4] |
number * number | number | 乗算 | jsonb_path_query('[4]', '2 * $[0]') | 8 |
number / number | number | 部門 | jsonb_path_query('[8.5]', '$[0] / 2') | 4.2500000000000000 |
number % number | number | モジュロ | jsonb_path_query('[32]', '$[0] % 10') | 2 |
value .type() | string | JSON アイテムの型(json_typeof を参照) | jsonb_path_query_array('[1, "2", {}]', '$[*].type()') | ["number", "string", "object"] |
value .size() | integer | 配列要素の数;非配列の場合は 1 | jsonb_path_query('{"m": [11, 15]}', '$.m.size()') | 2 |
value .double() | number | JSON 数値または文字列から変換された近似浮動小数点数 | jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') | 3.8 |
number .ceiling() | integer | 指定された数以上で、最も近い整数 | jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') | 2 |
number .floor() | integer | 与えられた数以下で最も近い整数 | jsonb_path_query('{"h": 1.7}', '$.h.floor()') | 1 |
number .abs() | number | 絶対値 | jsonb_path_query('{"z": -0.3}', '$.z.abs()') | 0.3 |
string .datetime() | datetime | 文字列から変換された日時値で、ISO 形式とのマッチング順序は次のとおりです:date、timetz、time、timestamptz、timestamp | jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime()') | "2015-8-1" |
string .datetime(template) | datetime | 指定された to_timestamp テンプレートを使用して変換された日時値 | jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') | ["12:30:00", "18:40:00"] |
object .keyvalue() | array | キーと値のペアを、"key"、"value"、および "id" フィールドを持つオブジェクトの配列として返します。"id" は、ソースオブジェクトの一意の識別子です。 | jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') | [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}] |
datetime()およびdatetime(template)メソッドは、to_timestampSQL 関数と同じ解析ルールを使用しますが、以下の 3 つの例外があります:一致しないテンプレートパターンは許可されません。テンプレート文字列で有効な区切り文字は、-、.、/、,、'、;、:、およびスペースのみです。テンプレート内の区切り文字は、入力文字列と完全に一致する必要があります。日時型を比較する必要がある場合、暗黙のキャストが適用されます:dateはtimestampまたはtimestamptzにキャストでき、timestampはtimestamptzに、timeはtimetzにキャストできます。最初のキャストを除くすべてのキャストは、現在のTimeZone設定に依存し、タイムゾーン対応のjsonpath関数内でのみ実行できます。
SQL/JSON フィルター式要素
以下の演算子および述語は、フィルター式(? (condition))内で使用できます。
| 要素 | 戻り値 | 説明 | 例 | 結果 |
|---|---|---|---|---|
value == value | boolean | 等価性比較(すべての JSON スカラー値で動作) | jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == 1)') | [1, 1] |
value != value<br>value <> value | boolean | 非等価性比較 | jsonb_path_query_array('[1, 2, 1, 3]', '$[*] ? (@ != 1)') | [2, 3] |
value < value | boolean | 未満比較 | jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ < 2)') | [1] |
value <= value | boolean | 以下比較 | jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <= "b")') | ["a", "b"] |
value > value | boolean | より大きい比較 | jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ > 2)') | [3] |
value >= value | boolean | 以上比較 | jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ >= 2)') | [2, 3] |
true | boolean | JSON 定数 true | jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == true)') | {"name": "Chris", "parent": true} |
false | boolean | JSON 定数 false | jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == false)') | {"name": "John", "parent": false} |
null | — | JSON 定数 null。null との比較は、SQL とは異なり、jsonpath では通常どおり動作します。 | jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') | "Mary" |
boolean && boolean | boolean | ブール値 AND | jsonb_path_query('[1, 3, 7]', '$[*] ? (@ > 1 && @ < 5)') | 3 |
boolean || boolean | boolean | ブール値 OR | jsonb_path_query('[1, 3, 7]', '$[*] ? (@ < 1 || @ > 5)') | 7 |
! boolean | boolean | ブール値 NOT | jsonb_path_query('[1, 3, 7]', '$[*] ? (!(@ < 5))') | 7 |
boolean is unknown | boolean | unknown | jsonb_path_query('[-1, 2, 7, "foo"]', '$[*] ? ((@ > 0) is unknown)') | "foo" |
string like_regex string [flag string] | boolean | 第 1 オペランドが第 2 オペランドで指定された正規表現と一致するかどうかをテストします。省略可能な flag 文字列には、以下の文字を含めることができます:i(大文字小文字を区別しない)、m(^ および $ が改行でマッチ)、s(. が改行とマッチ)、q(パターン全体をリテラル文字列としてクォート)。 | jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c" flag "i")') | ["abc", "aBdC", "abdacb"] |
string starts with string | boolean | 第 2 オペランドが第 1 オペランドの先頭部分文字列であるかどうかをテストします | jsonb_path_query('["John Smith", "Mary Stone", "Bob Johnson"]', '$[*] ? (@ starts with "John")') | "John Smith" |
exists (path_expression) | boolean | パス式が少なくとも 1 つの SQL/JSON アイテムと一致するかどうかをテストします。パス式がエラーを発生させる場合、unknown を返します。これにより、strict モードでの「キーなし」エラーが回避されます。 | jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] > 2)))') | [2, 4] |
SQL/JSON 正規表現
like_regex フィルターは、テキストを正規表現に対して照合します。たとえば、以下のパス照会は、配列内の英語の母音で始まるすべての文字列を大文字小文字を区別せずに照合します。
$[*] ? (@ like_regex "^[aeiou]" flag "i")like_regex パターンは JSON パス文字列リテラルであるため、バックスラッシュは 2 重にする必要があります。数字のみを含む文字列を照合するには、次のようにします。
$ ? (@ like_regex "^\\d+$")like_regex は、SQL/JSON 標準で定義された XQuery LIKE_REGEX 演算子ではなく、POSIX 正規表現エンジンを使用して実装されています。これにより、標準からのわずかな動作の違いが生じます。フラグ文字は、POSIX エンジンが期待する形式に変換されます。