示例表
后面的所有的表demo_json結構都是這個
create table demo_json(
`id` bigint unsigned not null auto_increment,
`json` json not null,
primary key (`id`)
)engine=innodb;
json_set
用于將對應的json已有的字段進行修改
語法
json_set(json_doc, path, value, [path, value, ...])
說明:
其中json_doc就是表中對應的json列,path就是json中對應的字段key,value就是對應的值,后面的都是這樣。返回值就是修改后的值
-- 插入數據
insert into demo_json(`json`) values ('{"ok":12}');
-- 更新數據
update demo_json set `json`=json_set(`json`, '$.f1', 2333, '$.f2', "v1");
-- 選擇數據
select `json` from demo_json;
-- 返回
{"f1": 2333, "f2": "v1", "ok": 12}
json_keys
返回對應文檔中的最上層的keys,如果內部還有更多嵌套的key,則是不會嵌套返回的
json_keys(json_doc[, path])
-- 無path參數,返回的是json_doc中的頂級key
-- 返回[a,b]
select json_kesy('{"a":12, "b":32}');
-- 返回[a, b, c]
select json_keys('{"a":12, "b":32, "c":{"ok":11, "kk":43}}');
-- 有path參數,則返回的是path對應文檔中的頂級key
-- 返回[ok, kk]
select json_keys('{"a":12, "b":32, "c":{"ok":11, "kk":43}}', '$.c');
json_type
返回對應文檔中的字段值的類型
json_type(value)
普通情況下直接返回,但是如果文檔的話,可以用函數json_extract(json_doc, path[, path...]) 進行提取即可
-- 返回integer
select json_type('12');
-- 返回double
select json_type('12.0');
-- 返回string
select json_type('"abc"');
-- 返回object
select json_type('{"a":12,"b":"v1"}');
-- 返回array
select json_type('["a", 1]');
-- 返回 {"a": 12, "b": "vv"}
select `json` from demo_json where id = 3;
-- 返回integer
select json_type(json_extract(`json`, '$.a')) from demo_json where id = 3;
-- 返回string
select json_type(json_extract(`json`, '$.b')) from demo_json where id = 3;
json_array
該函數用于將數據進行拼接,其實就有點像java中的new ArrayList() 這種
json_array(value[,value...])
-- 返回數組:["a", "1", 34]
select json_array('a', '1', 34);
json_depth
返回文檔的深度
json_depth(json_doc)
-- 返回1
select json_depth('[]');
-- 返回1
select json_depth('{}');
-- 返回1
select json_depth('12');
-- 返回1
select json_depth('"a"');
-- 返回2
select json_depth('[1]');
-- 返回2
select json_depth('[1, 2, 3, "a"]');
-- 返回2
select json_depth('{"a":12}');
-- 返回2
select json_depth('{"a":12, "b":"v"}');
-- 返回3
select json_depth('["a", {"b":12}]');
-- 返回3
select json_depth('[{"a":10}, {"b":12}]');
-- 返回3
select json_depth('{"a":12, "b":{"b1":12}}');
其中普通的空以及普通字段,深度是1級,二級的話,就是普通的數組和對象
json_quote
將非json_doc文檔格式的數據,轉換為文檔格式
json_quote(string)
-- 返回 ""
select json_quote('a');
-- 返回 "\"a\""
select json_quote('"a"');
-- 返回 ""
select json_quote('');
-- 返回 "[a, b]"
select json_quote('[a, b]');
-- 返回 "[\"a\", \"b\"]"
select json_quote('["a", "b"]');
json_valid
判斷值是否是json類型
json_valid(val)
-- 返回 null
select json_valid(null);
-- 返回 0
select json_valid('');
-- 返回 0
select json_valid('a');
-- 返回 1
select json_valid('[1,2]');
-- 返回 0
select json_valid('{a,1}');
-- 返回 1
select json_valid('{"a":12, "b":2}');
json_insert
給對應的文檔添加數據,這個給update的時候,這樣設置,更方便
select json_insert(json_doc, path, val[, path, val] ...)
-- 插入數據
insert into demo_json(`json`) values ('{"a":1, "b":2}');
-- {"a": 1, "b": 2}
select `json` from demo_json;
update demo_json set `json`=json_insert(`json`, '$.c', '3');
-- {"a": 1, "b": 2, "c": "3"}
select `json` from demo_json;
json_length
返回對應文檔的長度,我們知道文檔有這么幾種類型:標量、對象、數組
文件長度確定如下:
標量的長度為1。
數組的長度是數組元素的數量。
對象的長度是對象成員的數量。
該長度不計算嵌套數組或對象的長度。
-- 返回錯誤
select json_length('a');
select json_length(1);
select json_length('');
-- 0
select json_length('{}');
select json_length('[]');
select json_length('null');
-- 1
select json_length('"2"');
select json_length('[1]');
select json_length('{"a":1}');
-- 2
select json_length('[1, "a"]');
select json_length('{"a":1, "b":2}');
--------- 文檔類型 ---------
truncate demo_json;
insert into demo_json(`json`) values ('{"a": 1, "b": 2, "c": {"c1":1, "c2": 2}}');
-- {"a": 1, "b": 2, "c": {"c1":1, "c2": 2}}
select `json` from demo_json;
-- 1
select json_length(`json`, '$.a') from demo_json where id = 1;
-- 2
select json_length(`json`, '$.c') from demo_json where id = 1;
-- 3
select json_length(`json`) from demo_json where id = 1;
json_object
其實就是把一些值轉換為object格式,跟函數json_array有點相同
json_object([key, val[, key, val] ...])
json_pretty
該函數就是把文檔給打印出來,按照json格式進行打印
-- 1
select json_pretty('1');
-- "a"
select json_pretty('"a"');
-- 返回
-- [
-- 1,
-- 2,
-- "a"
-- ]
select json_pretty('[1, 2, "a"]');
-- 返回
-- {
-- "a": 1,
-- "b": 12,
-- "c": 39
-- }
select json_pretty('{"a":1, "b":12, "c":39}');
json_remove
從文檔中刪除指定的元素,然后返回
select json_remove(json_doc, path[, path] ...)
-- {"b": 2, "c": 3}
select json_remove('{"a":1, "b":2, "c":3}', '$.a');
-- {"c": 3}
select json_remove('{"a":1, "b":2, "c":3}', '$.a', '$.b');
-- [3, 2]
select json_remove('[12, 3, 2]', '$[0]');
-- [12, 2]
select json_remove('[12, 3, 2]', '$[1]');
------- 使用在字段上 ------
truncate demo_json;
insert into demo_json(`json`) values ('{"a":12, "b":2}');
update demo_json set `json`=json_remove(`json`, '$.a') where id = 1;
-- {"b": 2}
select `json` from demo_json;
json_search
該函數返回的是指定字符串的路徑,就是doc中的字段
json_search(json_doc, one_or_all, search_str[, escape_char[, path] ...])
說明:
- one_or_all:
'one':搜索到一個就直接返回
'all':搜索到所有的才返回,所有的字段會包裝成一個數組
- search_str:這個是搜索字段,默認是全部匹配,可以模糊匹配,采用%和,%表示匹配多個,表示匹配一個字符,這個跟like使用方式是一樣的
- escape_char:這個值轉義符,如果搜索的字符中有需要轉義的,則請在該字符這了添加,默認是\,通常情況下請填寫為空或者null,必須要有一個值
- path:更多的指定的字段
注意:該命令只是用于搜索字符使用
-- $.a
select json_search('{"a":"v"}', 'all', "v");
-- $.b
select json_search('{"a":"v", "b":"women is ok"}', 'all', "%is%");
-- $.a
select json_search('{"a":"v", "b":"women is ok", "c":{"c1":"v", "c2":"v2"}}', 'one', "v");
-- ["$.a", "$.c.c1"]
select json_search('{"a":"v", "b":"women is ok", "c":{"c1":"v", "c2":"v2"}}', 'all', "v");
-- ["$.a", "$.c.c1", "$.c.c2"]
select json_search('{"a":"v", "b":"women is ok", "c":{"c1":"v", "c2":"v2"}}', 'all', "%v%");
-- ["$.c.c1", "$.c.c2"]
select json_search('{"a":"v", "b":"women is ok", "c":{"c1":"v", "c2":"v2"}}', 'all', "%v%", null, '$.c');
-- 注意:數字搜索全部返回null,這個只是搜索字符的
select json_search('{"a":2}', 'all', 2);
select json_search('{"a":2}', 'all', '2');
select json_search('{"a":2}', 'all', '"2"');
select json_search('{"a":2}', 'all', '%2');
select json_search('{"a":2}', 'all', '%2%');
json_extract
該命令是從doc文件中提取對應的值
select json_extract(json_doc, path[, path] ...)
-- 1
select json_extract('{"a":1, "b":2}', '$.a');
-- [1, 2]
select json_extract('{"a":1, "b":2}', '$.a', '$.b');
-- [1, 2, {"c1": "v1", "c2": "v2"}]
select json_extract('{"a":1, "b":2, "c":{"c1":"v1", "c2":"v2"}}', '$.a', '$.b', '$.c');
json_unquote
該函數用于去除轉義符,和函數json_quote是作用相反
json_quote(string)
-- "\"123\""
select json_quote('"123"');
-- "123"
select json_quote('123');
-- 123
select json_unquote('123');
-- 123
select json_unquote('"123"');
json_contains
判斷一個文檔內容是否包含另外一個內容
json_contains(target, candidate[, path])
-- --- 對象包含:只有全部包含才返回1
-- 1
select json_contains('{"a":12}', '{"a":12}');
-- 0
select json_contains('{"a":1}', '{"a":12}');
-- 1
select json_contains('{"a":12, "b":2}', '{"a":12}');
-- --- 數組包含:只有全部包含才返回1
-- 1
select json_contains('[1, 2, "a"]', '1');
-- 1
select json_contains('[1, 2, "a"]', '"a"');
-- 1
select json_contains('[1, 2, "a"]', '[1, 2]');
-- 0
select json_contains('[1, 2, "a"]', '[1, 2, "b"]');
-- 嵌套包含,需要指定字段,其中字段是target的字段
-- 0
select json_contains('{"a":1, "b":{"b1":"v1", "b2":"v2"}}', '{"b2":"v2"}');
-- 1
select json_contains('{"a":1, "b":{"b1":"v1", "b2":"v2"}}', '{"b2":"v2"}', '$.b');
json_arrayagg
將結果集聚合為json數組,該函數一般用在group by的命令上面,這樣根據某個key聚合,其他的key就可以為數組形式了,這里用json_arrayagg就可以把那些值聚合為json數組
json_arrayagg(col_or_expr)
-- 建表
create table demo_json1(
`id` bigint unsigned not null auto_increment,
`num` int not null,
`json` json not null,
primary key(`id`)
)engine=innodb;
-- 添加數據
insert into demo_json1(`num`, `json`) values(1, '1');
insert into demo_json1(`num`, `json`) values(1, '{"a":1}');
insert into demo_json1(`num`, `json`) values(2, '{"a":1}');
insert into demo_json1(`num`, `json`) values(2, '{"a":2}');
insert into demo_json1(`num`, `json`) values(2, '{"a":3}');
-- 分組聚合
select `num`, json_arrayagg(`json`) as js from demo_json1 group by `num`;
json_objectagg
該函數用于將多個值聚集為一個json對象
json_objectagg(key, value)
說明:
其中key和value都是當前的數據,最后作為一個對象使用
CREATE TABLE `demo_json1` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`num` int NOT NULL,
`json` json NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- 數據
mysql> select * from demo_json1;
+----+-----+------+
| id | num | json |
+----+-----+------+
| 1 | 1 | "a" |
| 2 | 2 | "b" |
| 3 | 3 | "c" |
+----+-----+------+
-- 聚合查詢
{
"1": "a",
"2": "b",
"3": "c"
}
select json_objectagg(`num`,`json`) from demo_json1;
注意:
如果key對應的值相同,但是value對應的值不同,則這個時候怎么辦,默認是隨機的,按照查詢出來的順序指定,最后查到的就覆蓋前面的,如下
mysql> select * from demo_json1;
+----+-----+------+
| id | num | json |
+----+-----+------+
| 1 | 1 | "a" |
| 2 | 2 | "b" |
| 3 | 3 | "c" |
| 4 | 3 | "d" |
+----+-----+------+
-- 聚合查詢:
{
"1": "a",
"2": "b",
"3": "d"
}
select json_objectagg(`num`,`json`) from demo_json1;
如果我們要指定呢,則可以通過函數over子句,這個子句是怎么用,如下
-- over內部為空,則會返回所有的聚合
mysql> select json_objectagg(`num`,`json`) over() as js from demo_json1;
+--------------------------------+
| js |
+--------------------------------+
| {"1": "a", "2": "b", "3": "d"} |
| {"1": "a", "2": "b", "3": "d"} |
| {"1": "a", "2": "b", "3": "d"} |
| {"1": "a", "2": "b", "3": "d"} |
+--------------------------------+
-- 返回四條數據,因為數據內部有四條數據
mysql> select * from demo_json1;
+----+-----+------+
| id | num | json |
+----+-----+------+
| 1 | 1 | "a" |
| 2 | 2 | "b" |
| 3 | 3 | "c" |
| 4 | 3 | "d" |
+----+-----+------+
我們可以給over子句內部添加order by 進行排序,這樣就有了順序了,其中order by 官網中說是按照如下進行排序的
range between unbounded preceding and current row
mysql> select json_objectagg(`num`,`json`) over(order by `num`) as js from demo_json1;
+--------------------------------+
| js |
+--------------------------------+
| {"1": "a"} |
| {"1": "a", "2": "b"} |
| {"1": "a", "2": "b", "3": "d"} |
| {"1": "a", "2": "b", "3": "d"} |
+--------------------------------+
??為啥顯示是這個?官網上好像不是這樣顯示的,未知,暫時遺留吧
json_merge_patch
該函數用于對多個文檔進行合并
json_merge_patch(json_doc, json_doc[, json_doc] ...)
-- 在多個數據中有不是json對象的時候(包括json數組,json數組也認為不是對象),則返回最后一個
-- 2
select json_merge_patch('1', '2');
-- {"a": 1}
select json_merge_patch('1', '{"a":1}');
-- 2
select json_merge_patch('{"a":1}', '2');
-- 3
select json_merge_patch('{"a":1}', '2', '3');
-- {"c": 2}
select json_merge_patch('{"a":1}', '2', '3', '{"c":2}');
-- 若包含json數組,則也不是合并,而是為最后一個
-- {"a": 1}
select json_merge_patch('[1, 2]', '{"a":1}');
-- [1, 2]
select json_merge_patch('{"a":1}', '[1, 2]');
-- [1, 3, 5]
select json_merge_patch('{"a":1}', '[1, 2]', '[1,3, 5]');
-- {"b": 2}
select json_merge_patch('{"a":1}', '[1, 2]', '[1,3, 5]', '{"b":2}');
-- [3, 4]
select json_merge_patch('[1, 2]', '[3, 4]');
-- 所有的都為對象,則進行合并
-- {"a": 1, "c": 2}
select json_merge_patch('{"a":1}','{"c":2}');
-- 如果有key相同,則為最后一個,不同的則合并
-- {"a": 2}
select json_merge_patch('{"a":1}','{"a":2}');
-- {"a": 3}
select json_merge_patch('{"a":1}','{"a":2}', '{"a":3}');
-- {"a": 2, "b": 3}
select json_merge_patch('{"a":1, "b":3}','{"a":2}');
json_array_append
給某些元素的值添加對應的值
json_array_append(json_doc, path, val[, path, val] ...)
-- 對數組添加元素
-- [1]
select json_array_append('[]', '$', 1);
-- [1, 2, 3]
select json_array_append('[1]', '$', 2, '$', 3);
-- [[1, 1], 2, 3]
select json_array_append('[1, 2, 3]', '$[0]', 1);
-- 對對象添加數組元素
-- {"a": ["v", 1], "b": 1}
select json_array_append('{"a": "v", "b":1}', '$.a', 1);
-- [{"a": "v", "b": 1}, 1]
select json_array_append('{"a": "v", "b":1}', '$[0]', 1);
json_array_insert
該函數用于向已有的數組中添加對應的值,這個值的下標是函數的path指定的,指定后,其他的值向后退
json_array_insert(json_doc, path, value[, path, value] ...)
-- [10, 0, 1, 2]
select json_array_insert('[0, 1, 2]', '$[0]', 10);
-- 沒有變化,因為需要值為數組才行
select json_array_insert('{"a":1, "b":"v1"}', '$.a[0]', 10);
-- {"a": [10, 1], "b": "v1"}
select json_array_insert('{"a":[1], "b":"v1"}', '$.a[0]', 10);
json_storage_size
返回存儲的文檔的大小
json_storage_size(json_val)
-- 8
select json_storage_size('[1]');
-- 13
select json_storage_size('{"a":1}');
-- 21
select json_storage_size('{"a":1, "b":12}');
json_contains_path
該函數用于返回對應的path是否存在
json_contains_path(json_doc, one_or_all, path[, path] ...)
-- one 表示后面的路徑中只要有一個匹配上就算找到
-- 1
select json_contains_path('{"a":1, "b":2}', 'one', '$.a');
-- 1
select json_contains_path('{"a":1, "b":2}', 'one', '$.a', '$.b');
-- 0
select json_contains_path('{"a":1, "b":2}', 'one', '$.c');
-- 1
select json_contains_path('{"a":1, "b":2}', 'one', '$.a', '$.c');
-- all 要求所有的path都能夠找到,只要有一個不存在,則返回0
-- 1
select json_contains_path('{"a":1, "b":2}', 'all', '$.a');
-- 1
select json_contains_path('{"a":1, "b":2}', 'all', '$.a', '$.b');
-- 0
select json_contains_path('{"a":1, "b":2}', 'all', '$.c');
-- 0
select json_contains_path('{"a":1, "b":2}', 'all', '$.a', '$.c');
-- 嵌套內部
-- 1
select json_contains_path('{"a":1, "b":2, "c":{"k1":"v1"}}', 'one', '$.c.k1');
json_merge_preserve
該函數跟json_merge_path有點像,但是merge_path是只有為對象才會合并,而當前這個函數沒有那么多限制,會將所有的數據都合并為數組
json_merge_preserve(json_doc, json_doc[, json_doc] ...)
-- 非對象的數據都會作為數組進行合并,而對象的相同的key合并,value會合并為數組
-- ["a", "b"]
select json_merge_preserve('"a"', '"b"');
-- [1, "a"]
select json_merge_preserve('1', '"a"');
-- {"a": 1, "b": 2}
select json_merge_preserve('{"a":1}', '{"b":2}');
-- [{"a": 1}, 1]
select json_merge_preserve('{"a":1}', '[1]');
-- {"a": [1, 2], "b": 3}
select json_merge_preserve('{"a":1}', '{"a":2, "b":3}');
參考:
官網json函數文檔
https://dev.mysql.com/doc/refman/8.0/en/json-function-reference.html