一、方法羅列
分類 函數 描述
1. 創建json
json_array 創建json數組
json_object 創建json對象
json_quote 將json轉為json字符串類型
2. 查詢json
json_contains 判斷是否包含某個json值
json_contains_path 判斷某個路徑是否包含json值
json_extract 提取json值
column->path json_extract 的簡寫,mysql 5.7.9 開始支持
json_keys 提取json中的鍵值為json數組
json_search 按給定字符串關鍵字搜索json,返回匹配的路勁
3.修改json
json_append 廢棄,mysql 5.7.9開始改名為json_array_append
json_array_append 末尾添加數組元素,如果原有值的數值或json對象,則轉成數組后,再添加元素
json_array_insert 插入數組元素
json_insert 插入值(插入新值,但不替換已經存在的舊值)
json_merge 合並json數組或對象
json_remove 刪除json數據
json_replace 替換值(只替換已存在的舊值)
json_unquote 去除json字符串的引號,將值轉成string類型
4. 返回json屬性
json_depth 返回json文檔的最大深度
json_length 返回json文檔的長度
json_type 返回值的類型
json_valid 判斷是否為合法json文檔
二、使用舉例
MySQL 5.7.8開始支持json類型
create table t (
id int,
js json,
primary key(id)
)
插入數據
insert into t values(1,'{"a":1,"s":"abc"}')
insert into t values(2,'[1,2,{"a":123}]')
insert into t values(3,'"str"')
insert into t values(4,'123')
直接提供字符串即可。還可以用JSON_Array和JSON_Object函數來構造
insert into t values(5,JSON_Object('key1',v1,'key2',v2))
insert into t values(4,JSON_Array(v1,v2,v3))
JSON_OBJECT([key, val[, key, val] ...])
JSON_ARRAY([val[, val] ...])
JSON_SET(json_doc, path, val[, path, val] ...)
修改數據
update t set js=json_set('{"a":1,"s":"abc"}','$.a',456,'$.b','bbb') where id=1
結果js={"a":456,"s":"abc","b":"bbb"}
如果set的下標超過數組長度,指揮添加到數組結尾
select json_set('[1,2,3]','$[0]',456,'$[3]','bbb')
結果[456,2,3,'bbb']
JSON_INSERT(json_doc, path, val[, path, val] ...)
如果不存在對應屬性則插入,否則不做任何變動
JSON_REPLACE(json_doc, path, val[, path, val] ...)
如果存在則替換,否則不做任何變動
select json_insert('{"a":1,"s":"abc"}','$.a',456,'$.b','bbb')
結果{"a":1,"s":"abc","b":"bbb"}
select json_replace('{"a":1,"s":"abc"}','$.a',456,'$.b','bbb')
結果{"a":456,"s":"abc"}
刪除數據
JSON_REMOVE(json_doc, path[, path] ...)如果存在則刪除對應屬性,否則不做任何變動
select JSON_REMOVE('{"a":456,"b":"789"}','$.a');
結果:{"b": "789"}
涉及數組時,三個函數與json_set基本一樣
特別注意:$.a 與 $[0] 的區別,json數組與對象的問題
SELECT JSON_INSERT('[{"a": 1, "b": 456}]','$[1]',888)
結果 : [{"a": 1, "b": 456}, 888]
SELECT JSON_INSERT('[{"a": 1, "b": 456}]','$[0]',888)
結果 : [{"a": 1, "b": 456}] //結果不變,認為0索引已經存在了,注意這里結果不是[{"a":1}]
select json_replace('{"a":1}','$[0]',456)
結果 :456 // 而非 [456]
select json_replace('{"a":1}','$[1]',456)
結果不變
其實對於 json_insert 和 json_replace 來說一般情況沒必要針對數組使用。
select json_remove('{"a":1}','$[0]')
結果不變
select json_remove('[{"a":1}]','$[0]')
結果 : []
涉及數組的時候要小心。
JSON_MERGE(json_doc, json_doc[, json_doc] ...) 將多個doc合並
select json_merge('[1,2,3]','[4,5]')
結果 : [1, 2, 3, 4, 5] // 數組簡單擴展
select json_merge('{"a":1}','{"b":2}')
結果 : {"a": 1, "b": 2} // 兩個對象直接合並
特殊還在數組:
select json_merge('123','45')
結果 : [123, 45] //兩個常量變為數組
select json_merge('{"a":1}','[1,2]')
結果 : [{"a": 1}, 1, 2] // 目標碰到數組,先轉換為[doc]
select json_merge('[1,2]','{"a":1}')
結果 : [1, 2, {"a": 1}] // 非數組追加到數組后面
JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...) 給指定的節點,添加元素,如果節點不是數組,則先轉換成[doc]
select json_Array_append('[1,2]','$[1]','456')
結果 : [1, [2, "456"]]
這里由於索引 1 位置為 2 ,不是數組,所以先轉為數組,在添加到其尾部
JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...) 在數組的指定下標處插入元素
SELECT JSON_ARRAY_INSERT('[1,2,3]','$[1]',4)
結果 : [1, 4, 2, 3]
SELECT JSON_ARRAY_INSERT('[1,[1,2,3],3]','$[1][1]',4)
結果 : [1, [1, 4, 2, 3], 3]
SELECT JSON_ARRAY_INSERT('[1,2,3]','$[0]',4,'$[1]',5)
結果 : [4, 5, 1, 2, 3] // 注意后續插入是在前面插入基礎上的,而非[4,1,5,2,3]
提取json信息的函數
JSON_KEYS(json_doc[, path]) 返回指定path的key
select json_keys('{"a":1,"b":2}')
結果 ["a","b"]
select json_keys('{"a":1,"b":[1,2,3]}','$.b')
結果 null //數組沒有key
JSON_CONTAINS(json_doc, val[, path]) 是否包含子文檔
select json_contains('{"a":1,"b":4}','{"a":0}')
結果 : 0
select json_contains('{"a":1,"b":4}','{"a":1}')
結果 : 1 // 包含
select json_contains('{"a":[1,2,3],"b":1}','[1,2]','$.a')
結果 : 1 // 數組包含則需要所有元素都存在
select json_contains('{"a":[1,2,3],"b":1}','[1,2,4]','$.a')
結果 : 0
select json_contains('{"a":[1,2,3],"b":1}','1','$.a')
結果 : 1 //元素存在數組元素中
JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...) 檢查路徑是否存在
select JSON_CONTAINS_PATH('{"a":1,"b":1}', 'one','$.a','$.c')
結果 : 1 // 只要存在一個
select JSON_CONTAINS_PATH('{"a":1,"b":1}', 'all','$.a','$.c')
結果 : 0 // 必須全部存在
select JSON_CONTAINS_PATH('{"a":1,"b":{"c":{"d":1}}}', 'one','$.b.c.d')
結果 : 1
select JSON_CONTAINS_PATH('{"a":1,"b":{"c":{"d":1}}}', 'all','$.b.c.d')
結果 : 1
JSON_EXTRACT(json_doc, path[, path] ...) 獲得doc中某個或多個節點的值。
select json_extract('{"a":81,"b":29}','$.a')
結果 : 81
select json_extract('{"a":[111,222,333],"b":232}','$.a[1]')
結果 : 222
select json_extract('{"a":{"a":1,"b":2,"c":3},"b":2}','$.a.*')
結果 : [1, 2, 3] // a.* 通配a所有屬性的值返回成數組。
select json_extract('{"a":{"a":1,"b":2,"c":3},"b":4}','$**.a')
結果 : [{"a": 1, "b": 2, "c": 3}, 1] //通配$中所有層次下的屬性b的值返回成數組
JSON_SEARCH(json_doc, one_or_all, search_str[,escape_char[,path]..])
select json_search('{"a":"xyzf","b":{"c":"sdf"}}','one','%f%')
結果 : "$.a" //和like一樣可以用%和_匹配,在所有節點的值中匹配,one只返回一個
select json_search('{"a":"xyzf","b":{"c":"sdf"}}','all','%f%')
結果 : ["$.a", "$.b.c"]
select json_search('{"a":"abc","b":{"c":"dad"}}','all','%a%',null,'$.b')
結果 : "$.b.c" //限制查找范圍
select json_search('{"a":"abc","b":{"c":"dad"},"c":{"b":"aaa"}}','all','%a%',null,'$**.b')
結果 : "$.b.c" // 查找范圍還可使用通配符!在每個匹配節點和其下查找
注意,只有json_extract和json_search中的path才支持通配,其他json_set,json_insert等都不支持。
JSON_LENGTH(json_doc[,path]) 返回數組的長度,如果是object則是屬性個數,常量為1
select json_length('[1,2,3]')
結果 : 3
select json_length('123')
結果 : 1
select json_length('{"a":1,"b":2}')
結果 : 2
JSON_DEPTH(json_doc) 返回doc 深度
