mysql處理json數據

MySQL 5.7.8開始支持 json類型.javascript

create table t(id int,js json,PRIMARY KEY (`id`))java

插入數據
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')mysql

直接提供字符串便可。還能夠用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))sql

JSON_OBJECT([key, val[, key, val] ...])
JSON_ARRAY([val[, val] ...])
json


JSON_SET(json_doc, path, val[, path, val] ...)
修改數據數組

update t set js=json_set('{"a":1,"s":"abc"}','$.a',456,'$.b','bbb') where id=1app

結果js={"a":456,"s":"abc","b":"bbb"}函數

path中$就表明整個doc,而後能夠用JavaScript的方式指定對象屬性或者數組下標等.
執行效果,相似json的語法
$.a=456
$.b="bbb".net

存在就修改,不存在就設置.對象

$.c.c=123
這個在javascript中會出錯,由於.c爲null。
可是在json_set('{}','$.c.c',123)中,不存在的路徑將直接被忽略。

特殊的對於數組,若是目標doc不是數組則會被轉換成[doc],而後再執行set,
若是set的下標超過數組長度,只會添加到數組結尾。

select json_set('{"a":456}','$[1]',123)
結果[{"a":456},123]。目標現被轉換成[{"a":456}],而後應用$[1]=123。

select json_set('"abc"','$[999]',123)
結果["abc",123]。

再舉幾個例子
select json_set('[1,2,3]','$[0]',456,'$[3]','bbb')
結果[456,2,3,'bbb']

注意:
對於javascript中
var a=[1,2,3]
a.a='abc'
是合法的,可是一旦a轉成json字符串,a.a就丟失了。

而在mysql中,這種算做路徑不存在,所以
select json_set('[1,2,3]','$.a',456)
結果仍是[1,2,3]

 

而後還有另外兩個版本
JSON_INSERT(json_doc, path, val[, path, val] ...)
若是不存在對應屬性則插入,不然不作任何變更

JSON_REPLACE(json_doc, path, val[, path, val] ...)
若是存在則替換,不然不作任何變更

這兩個操做卻是沒有javascript直接對應的操做
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_replace('{"a":1,"s":"abc"}','$.a','$.b')
結果{"s":"abc"}

涉及數組時,三個函數與json_set基本同樣
select json_insert('{"a":1}','$[0]',456)
結果不變,認爲0元素已經存在了,注意這裏結果不是[{"a":1}]

select json_insert('{"a":1}','$[999]',456)
結果追加到數組結尾[{"a":1},456]
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]','$','456')
結果[1,2,456]

select json_Array_append('[1,2]','$[0]','456')
結果[[1,456],2]。指定插在$[0]這個節點,這個節點非數組,因此等效爲
select json_Array_append('[[1],2]','$[0]','456')


JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)
在數組的指定下標處插入元素

SELECT JSON_ARRAY_INSERT('[1,2,3]','$[1]',4)
結果[1,4,2,3]。在$數組的下標1處插入

SELECT JSON_ARRAY_INSERT('[1,[1,2,3],3]','$[1][1]',4)
結果[1,[1,4,2,3],3]。在$[1]數組的下標1處插入

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":1}')
結果1

select json_contains('{"a":2,"b":1}','{"a":1}')
結果0

select json_contains('{"a":[1,2,3],"b":1}','[1,2]','$.a')
結果1。數組包含則須要全部元素都存在。

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}}}', 'one','$.a.c.d')
結果0。


JSON_EXTRACT(json_doc, path[, path] ...)
得到doc中某個或多個節點的值。

select json_extract('{"a":1,"b":2}','$.a')
結果1

select json_extract('{"a":[1,2,3],"b":2}','$.a[1]')
結果2
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}','$**.b')
結果[2,4]。通配$中全部層次下的屬性b的值返回成數組。

mysql5.7.9開始增長了一種簡寫方式:column->path

select id,js->'$.id' from t where js->'$.a'=1 order by js->'$.b'
等價於
select id,json_extract(js,'$.id') 
from t where json_extract(js,'$.a')=1
order by json_extract(js,'$.b')

 

JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])
強大的查詢函數,用於在doc中返回符合條件的節點,select則是在表中返回符合要求的紀錄。

select json_search('{"a":"abc","b":{"c":"dad"}}','one','%a%')

結果$.a。和like同樣能夠用%和_匹配,在全部節點的值中匹配,one只返回一個。

select json_search('{"a":"abc","b":{"c":"dad"}}','all','%a%')
結果["$.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","$.c.b"]。查找範圍還可以使用通配符!在每一個匹配節點和其下查找。
注意,只有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

可再跟path參數
select json_length('{"a":1,"b":[1,2,3]}','$.b')
結果3


JSON_DEPTH(json_doc)
返回doc深度
select json_depth('{}'),json_depth('[]'),json_depth('123')
結果1,1,1

select json_depth('[1,2,3,4,5,6]')
結果2

select json_depth('{"a":{"b":{"c":1}}}') 結果4

相關文章
相關標籤/搜索