GET_JSON_OBJECT 関数は、指定された JSON パス json_path を使用して、JSON または STRING 型の入力から文字列を抽出します。
コマンドの形式
STRING GET_JSON_OBJECT(JSON|STRING <json>, STRING <json_path>)
-- 一般的な例。 Alice を返します。
SELECT GET_JSON_OBJECT(JSON '{"name": "Alice", "age": 30}', '$.name');
注意事項
-
GET_JSON_OBJECTは、JSON パスの正規表現構文をサポートしていません。 -
新しいJSON データ型の JSON パスは、既存の仕様とは異なるため、互換性の問題が発生する可能性があります。
-
クエリステートメントに複数の
GET_JSON_OBJECT関数が存在し、それらがすべて同じ JSON データを処理する場合、関数は同じ JSON 文字列に対して複数回の解析と走査を繰り返し実行します。繰り返し呼び出すと、パフォーマンスに影響を与えたり、料金が発生したりする可能性があります。UDTF を組み合わせて JSON 形式のログデータを変換することで、関数の複数回呼び出しを回避できます。詳細については、「MaxCompute の組み込み関数と UDTF を利用した JSON 形式のログデータの変換」をご参照ください。 -
基になるフィールドの値が複数回エスケープされた JSON 文字列である場合、
GET_JSON_OBJECT関数はその値全体をプレーンな文字列として扱い、JSON 構造の解析に失敗して NULL を返します。このような場合は、REGEXP_EXTRACT_ALLなどの正規表現関数を使用して、正規表現によって文字列から直接目的のフィールド値を抽出できます。
パラメーターの説明
-
json:必須。処理対象の JSON データ。JSON または STRING の 2 種類の入力タイプをサポートします:
-
JSON型 :JSON データ型の値です。形式は{"Key":"Value", "Key":"Value",...}です。例:JSON '{"name": "Alice", "age": 30}'。 -
STRING 型: 入力が STRING 型の場合、以下の形式要件を満たす必要があります。
-
STRING の形式は
{Key:Value, Key:Value,...}です。例:'{"name": "Alice", "age": 30}'。 -
英語の二重引用符 (") は、2 つのバックスラッシュ (\\) でエスケープする必要があります。
-
英語の一重引用符 (') は、1 つのバックスラッシュ (\) でエスケープする必要があります。
-
-
-
json_path:必須。抽出するデータの JSON パス式で、
$で始まる STRING 型の式です。例:$.aliyun.test[0].demo。各文字の意味は次のとおりです:-
$:ルートノードを表します。 -
.または['']:子ノードを表し、JSON オブジェクトの解析に使用されます。例:$.store.book。JSON のキー自体に.が含まれている場合、['']で代用できます。['']を使用したデータ取得は、フラグ設定ステートメントSET odps.sql.udf.getjsonobj.new=true;を設定した場合にのみサポートされます。 -
[]:[number]は配列のインデックスを表し、0 から始まります。 -
*:[]のワイルドカードです。配列全体を返します。*はエスケープをサポートしていません。
-
戻り値の説明
STRING 型、つまり指定されたパスで抽出されたデータを返します。戻り値のルールは以下のとおりです。
-
json が有効で、 json_path が存在する場合、対応する文字列を返します。
-
json が空または不正な形式の場合、NULL を返します。
-
json_path に
[*]が含まれている場合、非 ARRAY 形式が返されます。強制的に統一された ARRAY 形式で返すには、SET odps.sql.force.getjsonobj.array.format=true;を設定します。 -
json_path が不正な場合、NULL を返します。
戻り値の動作:
-
Project/SessionレベルのフラグSET odps.sql.udf.getjsonobj.new=true/false;を設定することで、関数の戻り値の動作を制御できます。フラグの設定によって、関数の戻り値の動作は以下の 2 通りです。
重要SET odps.sql.udf.getjsonobj.new=true;の設定を推奨します。この設定により、関数の戻り値の動作がより標準的になり、データ処理が容易になり、パフォーマンスも向上します。 MaxCompute プロジェクトに JSON 予約文字のエスケープ動作を使用する既存のジョブがある場合は、検証せずにこの設定を直接使用するとエラーや正確性の問題が発生する可能性があるため、元の動作を維持することを推奨します。パラメーター設定
SET odps.sql.udf.getjsonobj.new=true;SET odps.sql.udf.getjsonobj.new=false;戻り値の動作
元の文字列を保持する方法で出力します。
JSON 予約文字をエスケープする方法で出力します。
戻り値も JSON 文字列であるため、引き続き解析できます。
REPLACEやREGEXP_REPLACEなどの関数でバックスラッシュを置換する必要はありません。改行文字 (\n) や引用符 (") などの JSON 予約文字は、文字列
'\n'、'\"'として表示されます。同じキーの解析
1 つの JSON オブジェクトに同じキーが出現しても、正常に解析できます。
-- 1 を返します。 SELECT GET_JSON_OBJECT('{"a":"1","a":"2"}', '$.a');1 つの JSON オブジェクトに同じキーが出現してはならず、解析できない可能性があります。
-- NULL を返します。 SELECT GET_JSON_OBJECT('{"a":"1","a":"2"}', '$.a');出力結果のソート順
出力結果は、JSON 文字列の元の順序で出力されます。
-- {"b":"1","a":"2"} を返します。 SELECT GET_JSON_OBJECT('{"b":{"b":"1","a":"2"},"a":"2"}', '$.b');出力結果は辞書順で出力されます。
-- {"a":"2","b":"1"} を返します。 SELECT GET_JSON_OBJECT('{"b":{"b":"1","a":"2"},"a":"2"}', '$.b'); -
Hive 互換モード
SET odps.sql.hive.compatible=true;を有効にすると、GET_JSON_OBJECT関数の戻り値の動作は強制的に元の文字列を保持するようになります。 -
2021 年 1 月 21 日以降に作成された MaxCompute プロジェクトでは、
GET_JSON_OBJECT関数の戻り値の動作はデフォルトで元の文字列を保持するようになっています。 -
2021 年 1 月 21 日より前に作成された MaxCompute プロジェクトでは、
GET_JSON_OBJECT関数の戻り値の動作はデフォルトで JSON 予約文字をエスケープするようになっています。 -
以下の例を実行すると、お使いの MaxCompute プロジェクトで
GET_JSON_OBJECT関数がどちらの動作であるかを判断できます。SELECT GET_JSON_OBJECT('{"a":"[\\"1\\"]"}', '$.a'); -- JSON 予約文字をエスケープする動作の場合の戻り値: [\"1\"] -- 元の文字列を保持する動作の場合の戻り値: ["1"]チケットをサブミットしてプロダクト技術サポートチームに連絡することで、プロジェクト内の
GET_JSON_OBJECT関数の戻り値の動作を元の文字列を保持する動作に切り替えることができます。これにより、セッションレベルで頻繁にプロパティを設定する必要がなくなります。
使用例
JSON 型の入力パラメーター
例 1: JSON 型データからキー 'a' と 'c' の値を取得
-- 1 を返します。
SELECT GET_JSON_OBJECT(JSON '{"a":1, "b":2}', '$.a');
-- NULL を返します。
SELECT GET_JSON_OBJECT(JSON '{"a":1, "b":2}', '$.c');
例2:json_pathが不正な場合、NULL を返します。
-- NULL を返します。
SELECT GET_JSON_OBJECT(JSON '{"a":1, "b":2}', '$invalid_json_path');
STRING 型の入力パラメーター
例 1: JSON オブジェクト src_json.json からの情報抽出
-- テストデータを準備します。
CREATE TABLE IF NOT EXISTS src_json (
json STRING
);
INSERT OVERWRITE TABLE src_json
VALUES
('{"store":
{"fruit":[{"weight":8,"type":"apple"},
{"weight":9,"type":"pear"}],
"bicycle":{"price":19.95,
"color":"red"}},
"email":"amy@only_for_json_udf_test.net",
"owner":"amy"}');
-- owner フィールドの情報を抽出します。 amy を返します。
SELECT GET_JSON_OBJECT(src_json.json, '$.owner') FROM src_json;
-- オプション:元の文字列を保持する方法で出力します。
SET odps.sql.udf.getjsonobj.new=true;
-- store.fruit フィールドの最初の配列情報を抽出します。 {"weight":8,"type":"apple"} を返します。
SELECT GET_JSON_OBJECT(src_json.json, '$.store.fruit[0]') FROM src_json;
-- 存在しないフィールドの情報を抽出します。 NULL を返します。
SELECT GET_JSON_OBJECT(src_json.json, '$.non_exist_key') FROM src_json;
例 2: 配列型 JSON データからの情報抽出
-- 2222 を返します。
SELECT GET_JSON_OBJECT('{"array":[["aaaa",1111],["bbbb",2222],["cccc",3333]]}','$.array[1][1]');
-- 元の文字列を保持する方法で出力します。
SET odps.sql.udf.getjsonobj.new=true;
-- ["h0","h1","h2"] を返します。
SELECT GET_JSON_OBJECT('{"aaa":"bbb","ccc":{"ddd":"eee","fff":"ggg","hhh":["h0","h1","h2"]},"iii":"jjj"}','$.ccc.hhh[*]');
-- JSON 予約文字をエスケープする方法で出力します。
SET odps.sql.udf.getjsonobj.new=false;
-- [\"h0\",\"h1\",\"h2\"] を返します。
SELECT GET_JSON_OBJECT('{"aaa":"bbb","ccc":{"ddd":"eee","fff":"ggg","hhh":["h0","h1","h2"]},"iii":"jjj"}','$.ccc.hhh[*]');
-- h1 を返します。
SELECT GET_JSON_OBJECT('{"aaa":"bbb","ccc":{"ddd":"eee","fff":"ggg","hhh":["h0","h1","h2"]},"iii":"jjj"}','$.ccc.hhh[1]');
例 3: . を含むキーを持つ JSON データからの情報抽出
-- テストデータを準備します。
CREATE TABLE json_test (id STRING, json STRING);
-- キーに . を含むデータを挿入します。
INSERT INTO TABLE json_test (id, json) VALUES
("1",
"{
\"China.beijing\":
{\"school\":
{\"id\":0,\"book\":
[{\"title\": \"A\",\"price\": 8.95},
{\"title\": \"B\",\"price\": 10.2}]
}
}
}"
);
-- キーに . を含まないデータを挿入します。
INSERT INTO TABLE json_test (id, json) VALUES
("2",
"{
\"China_beijing\":
{\"school\":
{\"id\":0,\"book\":
[{\"title\": \"A\",\"price\": 8.95},
{\"title\": \"B\",\"price\": 10.2}]
}
}
}"
);
-- 角括弧 [''] を使用して '.' を含むデータを解析します。
-- ここでは 'China.beijing' に含まれる 'id' の値を抽出し、0 を返します。
SELECT GET_JSON_OBJECT(json, "$['China.beijing'].school['id']") FROM json_test WHERE id =1;
-- 特殊文字を含まないデータの場合、'.' と [''] は両方とも有効で等価です。
-- ここでは 'China_beijing' に含まれる 'id' の値を抽出し、0 を返します。
SELECT GET_JSON_OBJECT(json, "$['China_beijing'].school['id']") FROM json_test WHERE id =2;
SELECT GET_JSON_OBJECT(json, "$.China_beijing.school['id']") FROM json_test WHERE id =2;
例4:JSON のキー自体に. が含まれている場合、[''] で代替できます
SET odps.sql.udf.getjsonobj.new=true;
-- 1 を返します。
SELECT GET_JSON_OBJECT('{"a.1":"1","a":"2"}', '$[\'a.1\']');
例 5: 空または不正な形式の JSON 入力
-- NULL を返します。
SELECT GET_JSON_OBJECT('','$.array[1][1]');
-- NULL を返します。
SELECT GET_JSON_OBJECT('"array":["aaaa",1111],"bbbb":["cccc",3333]','$.array[1][1]');
例 6: エスケープ文字を含む JSON 文字列
SET odps.sql.udf.getjsonobj.new=true;
-- "1" を返します。
SELECT GET_JSON_OBJECT('{"a":"\\"1\\"","b":"2"}', '$.a');
-- '1' を返します。
SELECT GET_JSON_OBJECT('{"a":"\'1\'","b":"2"}', '$.a');
例 7: 絵文字のサポート
-- 絵文字を返します。
SELECT GET_JSON_OBJECT('{"a":"<絵文字>"}', '$.a');
注意:DataWorks は現在、絵文字の入力をサポートしていません。データ統合などのツールを使用して絵文字に対応するエンコードされた文字列を MaxCompute に直接書き込み、GET_JSON_OBJECT 関数で処理する場合のみサポートされます。
関連ドキュメント
-
関連する関数の詳細については、「JSON 関数」をご参照ください。
-
ベストプラクティスについては、「OSS から MaxCompute への JSON データの移行」をご参照ください。
-
json_path の詳細については、「LanguageManual UDF」をご参照ください。