GET_JSON_OBJECT函數用於根據指定的JSON路徑json_path,從JSON字串或JSON類型資料中提取字串。
命令格式
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 PATH的正則文法。新JSON資料類型的JSON PATH與原有規範不同,可能存在相容性問題。
當查詢語句存在多個
GET_JSON_OBJECT函數且處理的都是同一個JSON資料時,函數會多次對同一個JSON字串做重複的解析遍曆,反覆調用可能影響效能併產生費用。可以通過結合UDTF轉換JSON格式日誌資料,避免多次調用函數,詳情請參見 利用MaxCompute內建函數及UDTF轉換JSON格式日誌資料。
參數說明
json:必填。待處理的JSON資料。支援JSON或STRING兩種輸入類型:
JSON類型:JSON資料類型。格式為
{"Key":"Value", "Key":"Value",...},例如JSON '{"name": "Alice", "age": 30}'。STRING類型:當輸入為STRING類型時,滿足格式要求如下:
STRING格式為
{Key:Value, Key:Value,...},例如'{"name": "Alice", "age": 30}'。英文雙引號("),需要兩個反斜線(\\)轉義。
英文單引號('),需要一個反斜線(\)轉義。
json_path:必填。需要提取的資料的JSON路徑運算式,以
$開頭,STRING類型,例如$.aliyun.test[0].demo。不同字元的含義如下:$:表示根節點。.或['']:表示子節點,用於解析JSON對象,例如$.store.book。當JSON的Key本身包含.時,可以用['']來替代。用
['']取數,僅在設定Flag的語句SET odps.sql.udf.getjsonobj.new=true;時支援。[]:[number]表示數組下標,從0開始。*:Wildcard for [],返回整個數組。*不支援轉義。
傳回值說明
返回STRING類型,即按照指定路徑提取出來的資料。返回規則如下:
當json合法且json_path存在時,則返回對應字串。
當json為空白或為非法格式時,返回NULL。
當json_path存在
[*]時,返回非ARRAY格式。若希望強制返回統一的ARRAY格式,需設定SET odps.sql.force.getjsonobj.array.format=true;。當json_path非法時,返回NULL。
返回行為說明:
支援通過設定
Project/Session層級FlagSET odps.sql.udf.getjsonobj.new=true/false;控制函數的返回方式。不同的Flag設定對應函數的兩種返回行為如下:
重要推薦使用
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'、'\"'顯示。相同Key解析
一個JSON對象中可以出現相同的Key,並成功解析。
-- 返回1。 SELECT GET_JSON_OBJECT('{"a":"1","a":"2"}', '$.a');一個JSON對象中不可以出現相同的Key,可能導致無法解析。
-- 返回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函數返回行為切換為保留原始字串,避免在Session層級頻繁設定屬性。
使用樣本
入參為JSON類型
樣本1:從JSON類型資料中,分別擷取指定 key值為a、key值為c時,對應value值。
-- 返回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);
-- 插入Key帶有.的資料。
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}]
}
}
}"
);
-- 插入Key不帶有.的資料。
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的Key本身包含.時,可以用['']來替代
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:支援EmojiEmoji對應的編碼字串
-- 返回Emoji符號。
SELECT GET_JSON_OBJECT('{"a":"<Emoji符號>"}', '$.a');注意:DataWorks 暫不支援輸入EmojiEmoji,僅支援通過Data Integration等工具直接將EmojiEmoji對應的編碼字串寫入MaxCompute,再用GET_JSON_OBJECT函數處理。相關文檔
更多相關函數,請參見JSON函數。
最佳實務案例,請參見JSON資料從OSS遷移至MaxCompute。
更多json_path資訊,請參見LanguageManual UDF。