このトピックでは、AnalyticDB for MySQL クラスターでサポートされている JSON 関数について説明します。
JSON_ARRAY_CONTAINS:JSON 配列に指定された
valueが含まれているかどうかを確認します。JSON_ARRAY_LENGTH:JSON 配列の長さを返します。
JSON_CONTAINS (バージョン 3.1.5.0 以降):指定されたパスに
candidate値が含まれているかどうかを確認します。パスが指定されていない場合、この関数はターゲットにcandidate値が含まれているかどうかを確認します。JSON_CONTAINS_PATH (バージョン 3.1.5.0 以降):JSON ドキュメントに指定されたパスのいずれか、またはすべてが含まれているかどうかを確認します。
JSON_EXTRACT:指定された
json_pathにある JSON ドキュメントからデータを抽出します。JSON_KEYS:
json_pathが指定されている場合、この関数は JSON ドキュメントの指定されたパスからすべてのキーを返します。json_pathが指定されていない場合、この関数はルートパス (json_path='$') からすべてのキーを返します。JSON_OVERLAPS (バージョン 3.1.10.6 以降):JSON ドキュメントに
candidate1、candidate2、candidate3などの指定された要素のいずれかが含まれているかどうかを確認します。JSON_REMOVE (バージョン 3.1.10.0 以降):
jsonドキュメントから指定されたjson_pathの要素を削除し、変更された文字列を返します。`array[json_path,json_path,...]` を使用して、削除する複数の要素を指定できます。JSON_SIZE:指定された
json_pathにある JSON オブジェクトまたは配列のサイズを返します。JSON_SET (バージョン 3.2.2.8 以降):指定された
json_pathにあるjsonドキュメントにデータを挿入または更新し、更新されたjsonドキュメントを返します。JSON_UNQUOTE (バージョン 3.2.2.11 以降):
json_valueから二重引用符を削除し、json_value内の特定のエスケープ文字をアンエスケープして、結果の値を返します。
JSON_ARRAY_CONTAINS
json_array_contains(json, value)説明:JSON 配列に指定された
valueが含まれているかどうかを確認します。入力値の型:
valueは数値型、文字列、または BOOLEAN にすることができます。戻り値の型:BOOLEAN。
例:
JSON 配列
[1, 2, 3]に要素 `2` が含まれているかどうかを確認します。文は次のとおりです。SELECT json_array_contains('[1, 2, 3]', 2);次の結果が返されます。
+-------------------------------------+ | json_array_contains('[1, 2, 3]', 2) | +-------------------------------------+ | 1 | +-------------------------------------+
JSON_ARRAY_LENGTH
json_array_length(json)説明:JSON 配列の長さを返します。
入力値の型:文字列または JSON。
戻り値の型:BIGINT。
例:
JSON 配列
[1, 2, 3]の長さを返します。文は次のとおりです。SELECT json_array_length('[1, 2, 3]');次の結果が返されます。
+--------------------------------+ | json_array_length('[1, 2, 3]') | +--------------------------------+ | 3 | +--------------------------------+
JSON_CONTAINS
`JSON_CONTAINS` 関数は、指定された JSON ドキュメントに特定の値が含まれているかどうかを確認します。クエリで JSON 配列インデックスを使用すると、全表スキャンや JSON ドキュメント全体の解析を回避できるため、クエリ効率が向上します。
JSON インデックスを使用しない場合
この構文は、カーネルバージョンが 3.1.5.0 以降のクラスターでのみサポートされています。
マイナーバージョンを表示および更新するには、AnalyticDB for MySQL コンソール の クラスター情報 ページにある 構成情報 セクションに移動してください。
json_contains(target, candidate[, json_path])説明:
json_pathが指定されている場合、この関数は指定されたパスにcandidate値が含まれているかどうかを確認します。値が含まれている場合は `1` を、含まれていない場合は `0` を返します。json_pathが指定されていない場合、この関数はターゲットにcandidate値が含まれているかどうかを確認します。値が含まれている場合は `1` を、含まれていない場合は `0` を返します。
ルールは次のとおりです。
targetとcandidateが両方ともプリミティブ型 (NUMBER、BOOLEAN、STRING、または NULL) の場合、それらが等しければ、ターゲットは候補を含んでいると見なされます。targetとcandidateが両方とも JSON 配列の場合、`candidate` のすべての要素が `target` のいずれかの要素に含まれていれば、ターゲットは候補を含んでいると見なされます。targetが配列でcandidateが配列でない場合、`candidate` が `target` のいずれかの要素に含まれていれば、ターゲットは候補を含んでいると見なされます。targetとcandidateが両方とも JSON オブジェクトの場合、`candidate` のすべてのキーが `target` にも存在し、かつ `candidate` の各キーの値が `target` の対応するキーの値に含まれていれば、ターゲットは候補を含んでいると見なされます。
入力値の型:
targetとcandidateは JSON 型です。json_pathは JSONPATH 型です。戻り値の型:BOOLEAN。
例:
パス
$.aに値 `1` が含まれているかどうかを確認します。文は次のとおりです。SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '1', '$.a') as result;次の結果が返されます。
+--------+ | result | +--------+ | 1 | +--------+パス
$.bに値 `1` が含まれているかどうかを確認します。文は次のとおりです。SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '1', '$.b') as result;次の結果が返されます。
+--------+ | result | +--------+ | 0 | +--------+{"d": 4}がターゲットに含まれているかどうかを確認します。文は次のとおりです。SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '{"d": 4}') as result;次の結果が返されます。
+--------+ | result | +--------+ | 0 | +--------+
JSON 配列インデックスを使用する場合
この構文は、カーネルバージョンが 3.1.10.6 以降のクラスターでのみサポートされています。
指定された JSON 列に対して JSON 配列インデックスを作成する必要があります。詳細については、「JSON 配列インデックスの作成」をご参照ください。
SQL クエリ文の前に
EXPLAINを追加して実行計画を表示できます。実行計画に `ScanFilterProject` 演算子が含まれていない場合、JSON 配列インデックスは正常に使用されています。含まれている場合、インデックスは使用されていません。
json_contains(json_path, cast('[candidate1,candidate2,candidate3]' as json)) 説明:指定された JSON ドキュメントに
candidate1、candidate2、candidate3などの指定されたすべての要素が含まれているかどうかを確認します。入力値のデータ型:値
candidate1,candidate2,candidate3,...はすべて同じデータ型 (数値または文字列) である必要があります。戻り値の型:VARCHAR。
例:
指定された JSON 列
vjにCP-018673とCP-018671が含まれているかどうかを確認します。SELECT json_contains(vj, cast('["CP-018673","CP-018671"]' AS json)) FROM json_test;次の結果が返されます。
+------------------------------------------------------------+ |json_contains(vj, cast('["CP-018673","CP-018671"]' AS json))| | +------------------------------------------------------------+ | 0 | +------------------------------------------------------------+ | 0 | +------------------------------------------------------------+ | 1 | +------------------------------------------------------------+ | 0 | +------------------------------------------------------------+ | 0 | +------------------------------------------------------------+指定された JSON 列
vjにCP-018673、1、2が含まれているかどうかを確認します。SELECT json_contains(vj, cast('["CP-018673",1,2]' AS json)) FROM json_test;次の結果が返されます。
+------------------------------------------------------------+ |json_contains(vj, cast('["CP-018673","CP-018671"]' AS json))| | +------------------------------------------------------------+ | 0 | +------------------------------------------------------------+ | 1 | +------------------------------------------------------------+ | 1 | +------------------------------------------------------------+ | 0 | +------------------------------------------------------------+ | 1 | +------------------------------------------------------------+
JSON_CONTAINS_PATH
json_contains_path(json, one_or_all, json_path[, json_path,...])この関数は、カーネルバージョンが 3.1.5.0 以降のクラスターでのみサポートされています。
マイナーバージョンを表示および更新するには、AnalyticDB for MySQL コンソール の クラスター情報 ページにある 構成情報 セクションに移動してください。
コマンドの説明:指定されたパスが JSON オブジェクトに存在するかどうかを確認します。
one_or_allが'one'に設定されている場合、JSON ドキュメントに指定されたパスのいずれかが含まれていれば、関数は `1` を返します。それ以外の場合は `0` を返します。one_or_allが'all'に設定されている場合、JSON ドキュメントに指定されたすべてのパスが含まれていれば、関数は `1` を返します。それ以外の場合は `0` を返します。
入力値の型:
jsonは JSON 型です。one_or_allは VARCHAR 型で、'one'または'all'(大文字と小文字を区別しない) を指定できます。json_pathはパス式です。戻り値の型:BOOLEAN。
例:
JSON ドキュメントにパス
$.aと$.eの少なくとも 1 つが含まれているかどうかを確認します。文は次のとおりです。SELECT json_contains_path(json '{"a": 1, "b": 2, "c": {"d": 4}}', 'one', '$.a', '$.e') AS RESULT;次の結果が返されます。
+--------+ | result | +--------+ | 1 | +--------+JSON ドキュメントにパス
$.aと$.eの両方が含まれているかどうかを確認します。文は次のとおりです。SELECT json_contains_path(json '{"a": 1, "b": 2, "c": {"d": 4}}', 'all', '$.a', '$.e') AS RESULT;次の結果が返されます。
+--------+ | result | +--------+ | 0 | +--------+
JSON_EXTRACT
`JSON_EXTRACT` 関数の戻り値は、JSON 型の列と同様に、
ORDER BYをサポートしていません。`JSON_EXTRACT` 関数を `JSON_UNQUOTE` 関数と併用する場合は、まず CAST AS VARCHAR を使用して `JSON_EXTRACT` の戻り値を VARCHAR 型に変換する必要があります。変換された値は、`JSON_UNQUOTE` 関数の入力パラメーターとして使用できます。
json_extract(json, json_path)説明:指定された
json_pathにある JSON ドキュメントから値を抽出します。jsonドキュメント内のキーに$や.などの特殊文字が含まれている場合、json_pathのフォーマットは'$["Key"]'である必要があります。たとえば、キーが
$dataの場合、`json_path` は'$["$data"]'である必要があります。入力値の型:文字列または JSON。
戻り値の型:JSON。
例:
配列
[10, 20, [30, 40]]からパス `$[0]` の値を返します。文は次のとおりです。SELECT json_extract('[10, 20, [30, 40]]', '$[0]');次の結果が返されます。
+-------------------------------------------+ | json_extract('[10, 20, [30, 40]]', '$[0]') | +-------------------------------------------+ | 10 | +-------------------------------------------+{"id":"1","$date":"12345"}からパス `$date` の値を返します。文は次のとおりです。SELECT JSON_EXTRACT('{"id":"1","$date":"12345"}', '$["$date"]');次の結果が返されます。
+---------------------------------------------------------+ |JSON_EXTRACT('{"id":"1","$date":"12345"}', '$["$date"]') | +---------------------------------------------------------+ | "12345" | +---------------------------------------------------------+
JSON_KEYS
json_keys(json[, json_path])説明
json_pathが指定されている場合、この関数は JSON ドキュメントの指定されたパスからすべてのキーを返します。json_pathが指定されていない場合、この関数はルートパス (json_path='$') からすべてのキーを返します。
入力値の型:JSON 型のパラメーターのみがサポートされています。
次の方法で JSON データを構築できます。
JSON データを直接使用します。例:
json '{"a": 1, "b": {"c": 30}}'。CAST 関数を使用して、文字列を明示的に JSON データにキャストします。例:
CAST('{"a": 1, "b": {"c": 30}}' AS json)。
戻り値の型:JSON ARRAY。
例:
パス
$.bからすべてのキーを返します。文は次のとおりです。SELECT json_keys(CAST('{"a": 1, "b": {"c": 30}}' AS json),'$.b');次の結果が返されます。
+-----------------------------------------------------------+ | json_keys(CAST('{"a": 1, "b": {"c": 30}}' AS json),'$.b') | +-----------------------------------------------------------+ | ["c"] | +-----------------------------------------------------------+ルートパスからすべてのキーを返します。文は次のとおりです。
SELECT JSON_KEYS(json '{"a": 1, "b": {"c": 30}}');次の結果が返されます。
+--------------------------------------------+ | JSON_KEYS(json '{"a": 1, "b": {"c": 30}}') | +--------------------------------------------+ | ["a","b"] | +--------------------------------------------+
JSON_OVERLAPS
この構文は、カーネルバージョンが 3.1.10.6 以降のクラスターでのみサポートされています。
指定された JSON 列に対して JSON 配列インデックスを作成する必要があります。詳細については、「JSON 配列インデックスの作成」をご参照ください。
SQL クエリ文の前に
EXPLAINを追加して実行計画を表示できます。実行計画に `ScanFilterProject` 演算子が含まれていない場合、JSON 配列インデックスは正常に使用されています。含まれている場合、インデックスは使用されていません。
json_overlaps(json, cast('[candidate1,candidate2,candidate]' as json)) 説明:指定された JSON ドキュメントに
candidate1、candidate2、candidate3などの指定された要素のいずれかが含まれているかどうかを確認します。入力値のデータ型:
candidate1,candidate2,candidate3,...は数値型または文字列型にすることができ、すべての値は同じデータ型である必要があります。戻り値の型:VARCHAR。
例:
指定された JSON 列
vjからCP-018673を含むデータを返します。SELECT * FROM json_test WHERE json_overlaps(vj, cast('["CP-018673"]' AS json));次の結果が返されます。
+-----+----------------------------------------------------------------------------+ | id | vj | +-----+----------------------------------------------------------------------------+ | 2 | ["CP-018673", 1, false] | +-----+----------------------------------------------------------------------------+ | 3 | ["CP-018673", 1, false, {"a": 1}] | +-----+----------------------------------------------------------------------------+ | 5 | ["CP-018673","CP-018671","CP-018672","CP-018670","CP-018669","CP-018668"] | +-----+----------------------------------------------------------------------------+指定された JSON 列
vjから、要素1、2、または3のいずれかを含むデータを返します。SELECT * FROM json_test WHERE json_overlaps(vj, cast('[1,2,3]' AS json))次の結果が返されます。
+-----+-------------------------------------+ | id | vj | +-----+-------------------------------------+ | 1 | [1,2,3] | +-----+-------------------------------------+ | 2 | ["CP-018673", 1, false] | +-----+-------------------------------------+ | 3 | ["CP-018673", 1, false, {"a": 1}] | +-----+-------------------------------------+
JSON_REMOVE
`JSON_REMOVE` 関数は、カーネルバージョンが 3.1.10.0 以降のクラスターでのみサポートされています。
マイナーバージョンを表示および更新するには、AnalyticDB for MySQL コンソール の クラスター情報 ページにある 構成情報 セクションに移動してください。
json_remove(json,json_path)
json_remove(json,array[json_path,json_path,...])説明:
jsonドキュメントから指定されたjson_pathの要素を削除し、変更された文字列を返します。`array[json_path,json_path,...]` を使用して、削除する複数の要素を指定できます。入力値の型:
jsonは JSON 形式の VARCHAR 文字列です。json_pathは JSON 形式の VARCHAR 文字列です。戻り値の型:VARCHAR。
例
パス
$.glossary.GlossDivの要素を削除し、変更された文字列を返します。文は次のとおりです。SELECT json_remove( '{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }' , '$.glossary.GlossDiv') a;次の結果が返されます。
{"glossary":{"title":"example glossary"}}パス
$.glossary.titleと$.glossary.GlossDiv.titleの要素を削除し、変更された文字列を返します。文は次のとおりです。SELECT json_remove( '{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }' , array['$.glossary.title', '$.glossary.GlossDiv.title']) a;次の結果が返されます。
{"glossary":{"GlossDiv":{"GlossList":{"GlossEntry":{"GlossTerm":"Standard Generalized Markup Language","GlossSee":"markup","SortAs":"SGML","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"ID":"SGML","Acronym":"SGML","Abbrev":"ISO 8879:1986"}}}}}
JSON_SIZE
json_size(json, json_path)説明:指定された
json_pathにある JSON オブジェクトまたは配列のサイズを返します。説明json_pathが JSON オブジェクトまたは配列を指していない場合、この関数は `0` を返します。入力値の型:文字列または JSON。
戻り値の型:BIGINT。
例:
json_pathが JSON オブジェクトを指しています。文は次のとおりです。SELECT json_size('{"x":{"a":1, "b": 2}}', '$.x') as result;次の結果が返されます。
+--------+ | result | +--------+ | 2 | +--------+json_pathが JSON オブジェクトまたは配列を指していません。文は次のとおりです。SELECT json_size('{"x": {"a": 1, "b": 2}}', '$.x.a') as result;次の結果が返されます。
+--------+ | result | +--------+ | 0 | +--------+
JSON_SET
`JSON_SET` 関数は、カーネルバージョンが 3.2.2.8 以降のクラスターでのみサポートされています。
マイナーバージョンを表示および更新するには、AnalyticDB for MySQL コンソール の クラスター情報 ページにある 構成情報 セクションに移動してください。
json_set(json, json_path, value[, json_path, value] ...)説明:指定された
json_pathにあるjsonドキュメントにデータを挿入または更新し、更新されたjsonドキュメントを返します。jsonまたはjson_pathが null の場合、関数は null を返します。jsonドキュメントが有効な JSON 形式でない場合、またはjson_pathが有効なパス式でない場合、例外がスローされます。指定された
json_pathが存在する場合、その値はvalueで上書きされます。指定された
json_pathがjsonドキュメントに存在しない場合:json_pathが JSON オブジェクトを指している場合、valueはjson_pathで指定された場所に新しい要素として追加されます。json_pathが JSON 配列を指している場合、この関数は指定されたjson_pathの前の位置にデータが存在するかどうかを確認します。データが存在しない場合、`null` 値が追加されてギャップが埋められてからvalueが挿入されます。それ以外の場合、valueは直接挿入されます。その他の場合、例外がスローされます。
入力値の型:
json:VARCHAR または JSON。json_path:VARCHAR。value:BOOLEAN、TINYINT、SMALLINT、INT、BIGINT、FLOAT、DOUBLE、DECIMAL、VARCHAR、VARBINARY、DATE、DATETIME、TIMESTAMP、または TIME。
戻り値の型:JSON。
例:
json_pathが null のjsonドキュメントにデータを挿入します。SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', null, '10');結果:
+------------------------------------------------+ | JSON_SET('{ "a": 1, "b": [2, 3]}', NULL, '10') | +------------------------------------------------+ | null | +------------------------------------------------+json_pathが有効なパス式でないjsonドキュメントにデータを挿入します。SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.b.c', '10');結果:
Failed to execute json_set() for json_path: $.b.cjson_path1が存在し、json_path2が存在せず JSON オブジェクトを指しているjsonドキュメントにデータを挿入します。SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]');結果:
+-----------------------------------------------------------------------+ | JSON_SET('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') | +-----------------------------------------------------------------------+ | {"a":10,"b":[2,3],"c":"[true, false]"} | +-----------------------------------------------------------------------+指定された
json_pathが存在せず、JSON 配列を指しているjsonドキュメントにデータを挿入します。SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.b[4]', '[true, false]');結果:
+----------------------------------------------------------------+ | JSON_SET('{ "a": 1, "b": [2, 3]}', '$.b[4]', '[true, false]') | +----------------------------------------------------------------+ | {"a":1,"b":[2,3,null,null,"[true, false]"]} | +----------------------------------------------------------------+
JSON_UNQUOTE
json_unquote(json_value)この関数は、カーネルバージョンが 3.1.5.0 以降のクラスターでのみサポートされています。
マイナーバージョンを表示および更新するには、AnalyticDB for MySQL コンソール の クラスター情報 ページにある 構成情報 セクションに移動してください。
このコマンドは、
json_valueから二重引用符を削除し、特定のエスケープ文字をアンエスケープして、結果の値を返します。AnalyticDB for MySQL は
json_valueを検証しません。この関数は、json_valueが JSON 構文に準拠しているかどうかに関係なく、説明されているロジックに基づいて値を処理します。サポートされているエスケープ文字を次の表に示します。
アンエスケープ前
アンエスケープ後
\"二重引用符 (
")。\bバックスペース。
\fフォームフィード。
\nラインフィード。
\rキャリッジリターン。
\tタブ。
\\バックスラッシュ (
\)。\uXXXXUTF-8 文字表現。
入力値の型:VARCHAR。
戻り値の型:VARCHAR。
例:
引用符を外した文字列
abcを返します。文は次のとおりです。SELECT json_unquote('"abc"');次の結果が返されます。
+-----------------------+ | json_unquote('"abc"') | +-----------------------+ | abc | +-----------------------+次の文は、引用符を外して解析された文字列を返します。
SELECT json_unquote('"\\t\\u0032"');結果は次のとおりです。
+------------------------------+ | json_unquote('"\\t\\u0032"') | +------------------------------+ | 2 | +------------------------------+
付録:JSON Path 構文
使用方法
JSON オブジェクト内の指定されたキーにアクセスするには、
$.keyName[.keyName]...を使用します。JSON 配列の N 番目の要素にアクセスするには、
$[nonNegativeInteger]を使用します。ここで、n は非負の整数です。JSON オブジェクトにネストされた JSON 配列の N 番目の要素にアクセスするには、
$.keyName[.keyName]...[nonNegativeInteger]を使用します。ここで、n は非負の整数です。
注意事項
AnalyticDB for MySQL の JSON Path 構文は、* および ** ワイルドカード文字をサポートしていません。これは、'$.*'、'$.hobbies[*]'、'$.address.**'、'$.hobbies.**' などの式がサポートされていないことを意味します。
例
次の JSON データがあると仮定します。
{
"name": "Alice",
"age": 25,
"address": {
"city": "Hangzhou",
"zip": "10001"
},
"hobbies":["reading", "swimming", "cycling"]
}説明 | 正しい例 | 誤った例 |
キー `name` の値にアクセス | $.name | name |
ネストされたオブジェクト内のキー `city` の値にアクセス | $.address.city | $.address[0] |
JSON 配列 `hobbies` の最初の要素にアクセス | $.hobbies[0] | $.hobbies.[0] |
よくある質問
JSON_OVERLAPS 関数の使用時に java.lang.NullPointerException エラーが発生する場合の解決策
原因:このエラーは、`ALTER` 文を使用して JSON インデックスを作成したものの、`BUILD` 操作が実行されていないか、まだ完了していない場合に発生します。この場合、JSON インデックスはアクティブではありません。
解決策:
`BUILD` 操作が実行されていない場合:
AnalyticDB for MySQL クラスターは、特定の条件が満たされると自動的に `BUILD` タスクをトリガーします。また、手動で `BUILD` タスクをトリガーすることもできます。
`BUILD` 操作が実行された場合:
次の文を実行して、`BUILD` タスクのステータスを照会できます。返された結果の
statusフィールドがFINISHの場合、`BUILD` 操作は完了しています。SELECT table_name, schema_name, status FROM INFORMATION_SCHEMA.KEPLER_META_BUILD_TASK ORDER BY create_time DESC LIMIT 10;
`BUILD` の詳細については、「BUILD」をご参照ください。
参考
JSON:JSON データ型について説明します。
JSON インデックス:JSON オブジェクトと配列のインデックスを作成する方法について説明します。