查询和修改 JSON 值
seekdb 支持查询并引用 JSON 值,支持通过路径表达式提取部分 JSON 文档或修改 JSON 文档的部分内容。
引用 JSON 值
seekdb 支持如下两种方式查询并引用 JSON 值:
-
通过 "->"符号引用 JSON 数据中的一个带双引号的键值。
-
通过 "->>"'符号引用 JSON 数据中的一个不带双引号的键值。
示例如下:
obclient> SELECT c->"$.name" AS name FROM jn WHERE g <= 2;
+---------+
| name |
+---------+
| "Fred" |
| "Wilma" |
+---------+
2 rows in set
obclient> SELECT c->>"$.name" AS name FROM jn WHERE g <= 2;
+-------+
| name |
+-------+
| Fred |
| Wilma |
+-------+
2 rows in set
obclient> SELECT JSON_UNQUOTE(c->'$.name') AS name
FROM jn WHERE g <= 2;
+-------+
| name |
+-------+
| Fred |
| Wilma |
+-------+
2 rows in set
由于 JSON 文件是有层级的,所以 JSON 函数需要通过路径表达式提取部分 JSON 文档或修改 JSON 文档的部分内容,还可以指定在文档中的操作位置。
seekdb 使用路径语法"前导 $ 字符+符号选择器"来表示正在访问的 JSON 文档,符号选择器的类型如下:
-
符号"." 表示要访问的键名称。不带引号的名称在路径表达式中是不合法的(例如空格),所以必须在双引号内指定键名称。
示例如下:
obclient> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
+---------------------------------------------------------+
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
+---------------------------------------------------------+
| "Aztalan" |
+---------------------------------------------------------+
1 row in set -
符号"[N]"放在被选择的数组的路径后面,表示访问数组中位置 N 的值,其中 N 是 非负整数。数组位置是从零开始的整数。如果
path未选择数组值,则path[0]与path具有相同的计算值。示例如下:
obclient> SELECT JSON_SET('"x"', '$[0]', 'a');
+------------------------------+
| JSON_SET('"x"', '$[0]', 'a') |
+------------------------------+
| "a" |
+------------------------------+
1 row in set -
符号"[M to N]"用于指定数组值的子集或范围,即从位置 M 处的值开始,到位置 N 处的值结束。
示例如下:
obclient> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]');
+----------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[1 to 3]') |
+----------------------------------------------+
| [2, 3, 4] |
+----------------------------------------------+
1 row in set -
路径表达式还可以包含 * 或 ** 通配符,说明如下:
-
.[*]代表 JSON 对象中所有成员的值。 -
[*]表示计算 JSON 数组中所有元素的值。 -
prefix**suffix表示所有以命名前缀开头并以命名后缀结尾的路径。其中前缀部分不是必须的,而后缀部分是必须的。不允许使用"**"或者"***"来描述任意的路径。
信息对于文档中不存在的路径(计算为不存在的数据)会被计算为
NULL。 -
修改 JSON 值
seekdb 还支持通过 DML 语句修改完整的 JSON 值,以及在 UPDATE 语句中使用 JSON_SET()、JSON_REPLACE() 或 JSON_REMOVE() 函数来操作部分 JSON 值。
示例如下:
//插入全部数据
INSERT INTO json_tab(json_info) VALUES ('[1, {"a": "b"}, [2, "qwe"]]');
//插入部分数据
UPDATE json_tab SET json_info=JSON_ARRAY_APPEND(json_info, '$', 2) WHERE id=1;
//更新全部数据
UPDATE json_tab SET json_info='[1, {"a": "b"}]';
//更新部分数据
UPDATE json_tab SET json_info=JSON_REPLACE(json_info, '$[2]', 'aaa') WHERE id=1;
//删除部分数据
DELETE FROM json_tab WHERE id=1;
//通过函数更新部分数据
UPDATE json_tab SET json_info=JSON_REMOVE(json_info, '$[2]') WHERE id=1;
JSON 路径语法
路径由路径范围和一个或多个路径支路组成。对于 JSON 函数中使用的路径,范围是当前正在搜索或以其他方式操作的文档,由前导 $ 字符表示。
路径段由句点字符 (.) 分隔。数组中的元素用 [N] 表示,其中 N 是非负整数。键的名称必须是双引号字符串或有效的 ECMAScript 标识符。
路径表达式( 例如 JSON 文本)应使用 ascii、utf8 或 utf8mb4 字符集进行编码( 其他字符编码被隐式强制为 utf8mb4)。
完整的语法格式如下:
pathExpression: //路径表达式
scope[(pathLeg)*] //范围通过前导符 $ 描述
pathLeg:
member | arrayLocation | doubleAsterisk
member:
period ( keyName | asterisk )
arrayLocation:
leftBracket ( nonNegativeInteger | asterisk ) rightBracket
keyName:
ESIdentifier | doubleQuotedString
doubleAsterisk:
'**'
period:
'.'
asterisk:
'*'
leftBracket:
'['
rightBracket:
']'