JSON 路径表达式选择 JSON 文档中的一个值。
路径表达式可用于提取 JSON 文档的某些部分或修改的函数,以指定在该文档中的操作位置。例如,以下查询从 JSON 文档中提取具有键的成员的值:name
mysql> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
+---------------------------------------------------------+
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
+---------------------------------------------------------+
| "Aztalan" |
+---------------------------------------------------------+
路径语法使用前导字符来表示正在考虑的 JSON 文档,后跟选择器,这些选择器依次指示文档的更具体的部分:$
- 句点后跟键名,用于命名具有给定键的对象中的成员。如果不带引号的名称在路径表达式中不合法(例如,如果它包含空格),则必须在双引号内指定键名。
[N]
追加到选择数组的路径
中,将数组中位置N
处的值命名为该值。数组位置是从零开始的整数。如果path
未选择数组值,则 path
[0] 的计算结果与path
相同:
mysql> SELECT JSON_SET('"x"', '$[0]', 'a');
+------------------------------+
| JSON_SET('"x"', '$[0]', 'a') |
+------------------------------+
| "a" |
+------------------------------+
1 row in set (0.00 sec)
[M to N]
指定数组值的子集或范围,从位置M
处的值开始,到位置N
处的值结束。last
支持作为最右边数组元素索引的同义词。还支持数组元素的相对寻址。如果path
未选择数组值,则 path
[last] 的计算结果与路径
相同,如本节后面所示(请参见最右边的数组元素)。- 路径可以包含通配符或通配符:
*
**
.[*]
计算为 JSON 对象中所有成员的值。[*]
计算为 JSON 数组中所有元素的值。prefix**suffix
计算为以命名前缀开头并以命名后缀结尾的所有路径。
- 文档中不存在的路径(计算为不存在的数据)的计算结果为 。
NULL
让我们用三个元素引用这个 JSON 数组:$
[3, {"a": [5, 6], "b": 10}, [99, 100]]
然后:
$[0]
计算结果为 。3
$[1]
计算结果为 。{"a": [5, 6], "b": 10}
$[2]
计算结果为 。[99, 100]
$[3]
计算为(它引用第四个数组元素,它不存在)。NULL
由于 和 计算结果为非标量值,因此它们可以用作选择嵌套值的更具体的路径表达式的基础。例子:$[1]
$[2]
$[1].a
计算结果为 。[5, 6]
$[1].a[1]
计算结果为 。6
$[1].b
计算结果为 。10
$[2][0]
计算结果为 。99
如前所述,如果未加引号的键名在路径表达式中不合法,则必须用引号来命名键的路径组件。让我们参考这个值:$
{"a fish": "shark", "a bird": "sparrow"}
键都包含空格,必须用引号括起来:
$."a fish"
计算结果为 。shark
$."a bird"
计算结果为 。sparrow
使用通配符的路径的计算结果为可以包含多个值的数组:
mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*') |
+---------------------------------------------------------+
| [1, 2, [3, 4, 5]] |
+---------------------------------------------------------+
mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]');
+------------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') |
+------------------------------------------------------------+
| [3, 4, 5] |
+------------------------------------------------------------+
在下面的示例中,路径的计算结果为多个路径 ( 和 ),并生成匹配路径值的数组:$**.b
$.a.b
$.c.b
mysql> SELECT JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b') |
+---------------------------------------------------------+
| [1, 2] |
+---------------------------------------------------------+
范围从 JSON 数组。您可以将范围与关键字结合使用,以指定 JSON 数组的子集。例如,包括数组的第二个、第三个和第四个元素,如下所示:to
$[1 to 3]
mysql> 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 (0.00 sec)
语法为 ,其中M
和N
分别是 JSON 数组中一系列元素的第一个和最后一个索引。 N
必须大于M
; M
必须大于或等于 0。数组元素的索引从 0 开始。M to N
您可以在支持通配符的上下文中使用范围。
最右边的数组元素。支持将关键字作为数组中最后一个元素的索引的同义词。表单的表达式可用于相对寻址和范围内定义,如下所示:last
last - N
mysql> SELECT JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]');
+--------------------------------------------------------+
| JSON_EXTRACT('[1, 2, 3, 4, 5]', '$[last-3 to last-1]') |
+--------------------------------------------------------+
| [2, 3, 4] |
+--------------------------------------------------------+
1 row in set (0.01 sec)
如果针对非数组的值评估路径,则评估结果与将值包装在单元素数组中的结果相同:
mysql> SELECT JSON_REPLACE('"Sakila"', '$[last]', 10);
+-----------------------------------------+
| JSON_REPLACE('"Sakila"', '$[last]', 10) |
+-----------------------------------------+
| 10 |
+-----------------------------------------+
1 row in set (0.00 sec)
您可以使用列->路径以及 JSON 列标识符和 JSON 路径表达式作为JSON_EXTRACT(列,路径)的同义词。有关更多信息,请参见 第 12.18.3 节 "搜索 JSON 值的函数"。另请参 阅为生成的列编制索引以提供 JSON 列索引。
某些函数采用现有的 JSON 文档,以某种方式对其进行修改,然后返回生成的修改后的文档。路径表达式指示要在文档中进行更改的位置。例如,JSON_SET()、JSON_INSERT()和JSON_REPLACE()函数各自采用一个 JSON 文档,外加一个或多个路径值对,用于描述在何处修改文档和要使用的值。这些函数的不同之处在于它们如何处理文档中的现有值和不存在的值。
请考虑以下文档:
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
JSON_SET()替换存在路径的值,并为不存在的路径添加值:。
mysql> SELECT JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+--------------------------------------------+
| JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+--------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20, 2]] |
+--------------------------------------------+
在这种情况下,路径选择一个现有值 (),该值将替换为 path 参数 () 后面的值。该路径不存在,因此相应的值 () 将添加到 所选的值中。$[1].b[0]
true
1
$[2][2]
2
$[2]
JSON_INSERT()会添加新值,但不替换现有值:
mysql> SELECT JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+-----------------------------------------------+
| JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+-----------------------------------------------+
| ["a", {"b": [true, false]}, [10, 20, 2]] |
+-----------------------------------------------+
JSON_REPLACE()替换现有值并忽略新值:
mysql> SELECT JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+------------------------------------------------+
| JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+------------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20]] |
+------------------------------------------------+
路径值对从左到右进行计算。通过评估一对生成的文档将成为评估下一对的新值。
JSON_REMOVE()
采用 JSON 文档和一个或多个路径,这些路径指定要从文档中删除的值。返回值是原始文档减去文档中存在的路径选择的值:
mysql> SELECT JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]');
+---------------------------------------------------+
| JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]') |
+---------------------------------------------------+
| ["a", {"b": [true]}] |
+---------------------------------------------------+
这些路径具有以下效果:
$[2]
匹配并删除它。[10, 20]
- 元素中匹配的第一个实例并将其删除。
$[1].b[1]
false
b
- 第二个实例不匹配:该元素已被删除,路径不再存在,并且不起作用。
$[1].b[1]