搜索JSON值的函数
本节中的功能对JSON值执行搜索或比较操作,以从其中提取数据,报告数据是否在其中的某个位置或报告其中的数据的路径。在MEMBER OF()
操作者在本文中也记载。
JSON_CONTAINS(target,candidate[,path])
通过返回1或0指示给定的
candidate
JSON文档是否包含在target
JSON文档中,或者(如果提供了path
参数)指示是否在目标内的特定路径上找到候选对象。返回NULL
是否有任何参数为NULL
,或者path参数没有标识目标文档的一部分。如果发生错误target
或candidate
不是有效的JSON文档,或者如果path
参数不是一个有效的路径表达式或包含一个*
或**
通配符。要仅检查路径中是否存在任何数据,请
JSON_CONTAINS_PATH()
改用。以下规则定义了围堵:
- 当且仅当候选标量可比较且相等时,才包含在目标标量中。如果两个标量值具有相同的
JSON_TYPE()
类型,则它们是可比较的,但类型的值INTEGER
和DECIMAL
也可彼此比较。 - 当且仅当候选对象中的每个元素都包含在目标的某个元素中时,候选数组才包含在目标数组中。
- 当且仅当候选非数组包含在目标的某些元素中时,该候选非数组才包含在目标数组中。
- 当且仅当候选对象中的每个关键字在目标中存在一个具有相同名称的关键字并且与候选关键字相关联的值包含在与目标关键字相关联的值中时,候选对象才包含在目标对象中。
否则,候选值将不包含在目标文档中。
从MySQL 8.0.17开始,可以使用多值索引
JSON_CONTAINS()
对在InnoDB
表上使用的查询进行优化。有关更多信息,请参见多值索引。mysql>
SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}'; mysql>SET @j2 = '1'; mysql>SELECT JSON_CONTAINS(@j, @j2, '$.a'); +------------------------------- + | JSON_CONTAINS(@j, @j2, '$.a') | +------------------------------- + | 1 | +------------------------------- + mysql>SELECT JSON_CONTAINS(@j, @j2, '$.b'); +------------------------------- + | JSON_CONTAINS(@j, @j2, '$.b') | +------------------------------- + | 0 | +------------------------------- + mysql>SET @j2 = '{"d": 4}'; mysql>SELECT JSON_CONTAINS(@j, @j2, '$.a'); +------------------------------- + | JSON_CONTAINS(@j, @j2, '$.a') | +------------------------------- + | 0 | +------------------------------- + mysql>SELECT JSON_CONTAINS(@j, @j2, '$.c'); +------------------------------- + | JSON_CONTAINS(@j, @j2, '$.c') | +------------------------------- + | 1 | +------------------------------- +- 当且仅当候选标量可比较且相等时,才包含在目标标量中。如果两个标量值具有相同的
JSON_CONTAINS_PATH(json_doc,one_or_all,path[,path]...)
返回0或1以指示JSON文档是否包含给定路径中的数据。返回
NULL
是否有任何参数NULL
。如果json_doc
参数不是有效的JSON文档,任何path
参数不是有效的路径表达式,或者one_or_all
不是'one'
或,都会发生错误'all'
。要检查路径上的特定值,请
JSON_CONTAINS()
改用。如果文档中没有指定的路径,则返回值为0。否则,返回值取决于
one_or_all
参数:'one'
:如果文档中至少存在一个路径,则为1,否则为0。'all'
:如果文档中所有路径都存在,则为1,否则为0。
mysql>
SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}'; mysql>SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e'); +--------------------------------------------- + | JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e') | +--------------------------------------------- + | 1 | +--------------------------------------------- + mysql>SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e'); +--------------------------------------------- + | JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e') | +--------------------------------------------- + | 0 | +--------------------------------------------- + mysql>SELECT JSON_CONTAINS_PATH(@j, 'one', '$.c.d'); +---------------------------------------- + | JSON_CONTAINS_PATH(@j, 'one', '$.c.d') | +---------------------------------------- + | 1 | +---------------------------------------- + mysql>SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a.d'); +---------------------------------------- + | JSON_CONTAINS_PATH(@j, 'one', '$.a.d') | +---------------------------------------- + | 0 | +---------------------------------------- +JSON_EXTRACT(json_doc,path[,path]...)
从JSON文档返回数据,该数据是从与
path
参数匹配的文档部分中选择的。返回NULL
是否有任何参数NULL
在文档中找到值的路径。如果json_doc
参数不是有效的JSON文档或任何path
参数不是有效的路径表达式,则会发生错误。返回值由
path
参数匹配的所有值组成。如果这些参数有可能返回多个值,则匹配的值将按照与产生它们的路径相对应的顺序自动包装为一个数组。否则,返回值是单个匹配值。mysql>
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]'); +-------------------------------------------- + | JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]') | +-------------------------------------------- + | 20 | +-------------------------------------------- + mysql>SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]'); +---------------------------------------------------- + | JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]') | +---------------------------------------------------- + | [20, 10] | +---------------------------------------------------- + mysql>SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]'); +----------------------------------------------- + | JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]') | +----------------------------------------------- + | [30, 40] | +----------------------------------------------- +MySQL支持
->
将此函数用作此函数的简写形式,与2个参数一起使用,其中左侧是JSON
列标识符(不是表达式),右侧是要在列内匹配的JSON路径。column->path
当与两个参数一起使用时,该
->
运算符用作该JSON_EXTRACT()
函数的别名,左侧是列标识符,右侧是根据JSON文档(列值)评估的JSON路径。您可以在SQL语句中的任何位置使用此类表达式代替列标识符。SELECT
此处显示的两个语句产生相同的输出:mysql>
SELECT c, JSON_EXTRACT(c, "$.id"), g >FROM jemp >WHERE JSON_EXTRACT(c, "$.id") > 1 >ORDER BY JSON_EXTRACT(c, "$.name"); +------------------------------- +----------- +------ + | c | c ->"$.id" | g | +------------------------------- +----------- +------ + | {"id": "3", "name": "Barney"} | "3" | 3 | | {"id": "4", "name": "Betty"} | "4" | 4 | | {"id": "2", "name": "Wilma"} | "2" | 2 | +------------------------------- +----------- +------ + 3 rows in set (0.00 sec) mysql>SELECT c, c->"$.id", g >FROM jemp >WHERE c->"$.id" > 1 >ORDER BY c->"$.name"; +------------------------------- +----------- +------ + | c | c ->"$.id" | g | +------------------------------- +----------- +------ + | {"id": "3", "name": "Barney"} | "3" | 3 | | {"id": "4", "name": "Betty"} | "4" | 4 | | {"id": "2", "name": "Wilma"} | "2" | 2 | +------------------------------- +----------- +------ + 3 rows in set (0.00 sec)此功能不限于
SELECT
,如下所示:mysql>
ALTER TABLE jempADD COLUMN n INT; Query OK, 0 rows affected (0.68 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql>UPDATE jempSET n=1WHERE c->"$.id" = "4"; Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>SELECT c, c->"$.id", g, n >FROM jemp >WHERE JSON_EXTRACT(c, "$.id") > 1 >ORDER BY c->"$.name"; +------------------------------- +----------- +------ +------ + | c | c ->"$.id" | g | n | +------------------------------- +----------- +------ +------ + | {"id": "3", "name": "Barney"} | "3" | 3 | NULL | | {"id": "4", "name": "Betty"} | "4" | 4 | 1 | | {"id": "2", "name": "Wilma"} | "2" | 2 | NULL | +------------------------------- +----------- +------ +------ + 3 rows in set (0.00 sec) mysql>DELETE FROM jempWHERE c->"$.id" = "4"; Query OK, 1 row affected (0.04 sec) mysql>SELECT c, c->"$.id", g, n >FROM jemp >WHERE JSON_EXTRACT(c, "$.id") > 1 >ORDER BY c->"$.name"; +------------------------------- +----------- +------ +------ + | c | c ->"$.id" | g | n | +------------------------------- +----------- +------ +------ + | {"id": "3", "name": "Barney"} | "3" | 3 | NULL | | {"id": "2", "name": "Wilma"} | "2" | 2 | NULL | +------------------------------- +----------- +------ +------ + 2 rows in set (0.00 sec)(有关用于创建和填充刚刚显示的表的语句,请参见索引生成的列以提供JSON列索引。)
这也适用于JSON数组值,如下所示:
mysql>
CREATE TABLE tj10 (a JSON, b INT); Query OK, 0 rows affected (0.26 sec) mysql>INSERT INTO tj10 >VALUES ("[3,10,5,17,44]", 33), ("[3,10,5,17,[22,44,66]]", 0); Query OK, 1 row affected (0.04 sec) mysql>SELECT a->"$[4]"FROM tj10; +-------------- + | a ->"$[4]" | +-------------- + | 44 | | [22, 44, 66] | +-------------- + 2 rows in set (0.00 sec) mysql>SELECT *FROM tj10WHERE a->"$[0]" = 3; +------------------------------ +------ + | a | b | +------------------------------ +------ + | [3, 10, 5, 17, 44] | 33 | | [3, 10, 5, 17, [22, 44, 66]] | 0 | +------------------------------ +------ + 2 rows in set (0.00 sec)支持嵌套数组。使用的表达式的
->
求值就像NULL
在目标JSON文档中找不到匹配的键一样,如下所示:mysql>
SELECT *FROM tj10WHERE a->"$[4][1]" IS NOT NULL; +------------------------------ +------ + | a | b | +------------------------------ +------ + | [3, 10, 5, 17, [22, 44, 66]] | 0 | +------------------------------ +------ + mysql>SELECT a->"$[4][1]"FROM tj10; +-------------- + | a ->"$[4][1]" | +-------------- + | NULL | | 44 | +-------------- + 2 rows in set (0.00 sec)这与使用
JSON_EXTRACT()
以下情况下的情况相同:mysql>
SELECT JSON_EXTRACT(a, "$[4][1]")FROM tj10; +---------------------------- + | JSON_EXTRACT(a, "$[4][1]") | +---------------------------- + | NULL | | 44 | +---------------------------- + 2 rows in set (0.00 sec)column->>path
这是一种改进的单引号提取运算符。而
->
操作者简单地提取的值时,->>
在加法运算unquotes提取结果。换句话说,给定JSON
列值column
和路径表达式path
,以下三个表达式返回相同的值:JSON_UNQUOTE(
JSON_EXTRACT(column,path))
JSON_UNQUOTE(column
->
path)
column->>path
->>
可以JSON_UNQUOTE(JSON_EXTRACT())
在允许的任何地方使用该运算符。这包括(但不限于)SELECT
列表,WHERE
和HAVING
条款,并ORDER BY
和GROUP BY
条款。接下来的几条语句演示了
->>
与mysql客户端中其他表达式的一些运算符等效项:mysql>
SELECT *FROM jempWHERE g > 2; +------------------------------- +------ + | c | g | +------------------------------- +------ + | {"id": "3", "name": "Barney"} | 3 | | {"id": "4", "name": "Betty"} | 4 | +------------------------------- +------ + 2 rows in set (0.01 sec) mysql>SELECT c->'$.name'AS name ->FROM jempWHERE g > 2; +---------- + | name | +---------- + | "Barney" | | "Betty" | +---------- + 2 rows in set (0.00 sec) mysql>SELECT JSON_UNQUOTE(c->'$.name')AS name ->FROM jempWHERE g > 2; +-------- + | name | +-------- + | Barney | | Betty | +-------- + 2 rows in set (0.00 sec) mysql>SELECT c->>'$.name'AS name ->FROM jempWHERE g > 2; +-------- + | name | +-------- + | Barney | | Betty | +-------- + 2 rows in set (0.00 sec)请参阅索引已生成的列以提供JSON列索引,以获取用于
jemp
在刚刚显示的示例集中创建和填充表的SQL语句。此运算符也可以与JSON数组一起使用,如下所示:
mysql>
CREATE TABLE tj10 (a JSON, b INT); Query OK, 0 rows affected (0.26 sec) mysql>INSERT INTO tj10VALUES -> ('[3,10,5,"x",44]', 33), -> ('[3,10,5,17,[22,"y",66]]', 0); Query OK, 2 rows affected (0.04 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql>SELECT a->"$[3]", a->"$[4][1]"FROM tj10; +----------- +-------------- + | a ->"$[3]" | a ->"$[4][1]" | +----------- +-------------- + | "x" | NULL | | 17 | "y" | +----------- +-------------- + 2 rows in set (0.00 sec) mysql>SELECT a->>"$[3]", a->>"$[4][1]"FROM tj10; +------------ +--------------- + | a ->>"$[3]" | a ->>"$[4][1]" | +------------ +--------------- + | x | NULL | | 17 | y | +------------ +--------------- + 2 rows in set (0.00 sec)与一样
->
,->>
运算符总是在的输出中扩展EXPLAIN
,如以下示例所示:mysql>
EXPLAIN SELECT c->>'$.name'AS name ->FROM jempWHERE g > 2\G *************************** 1. row *************************** id : 1 select_type : SIMPLE table : jemp partitions : NULL type : range possible_keys : i key : i key_len : 5 ref : NULL rows : 2 filtered : 100.00 Extra : Using where 1 row in set, 1 warning (0.00 sec) mysql>SHOW WARNINGS \G*************************** 1. row *************************** Level : Note Code : 1003 Message : / * select#1 */ select json_unquote(json_extract(`jtest`.`jemp`.`c`,'$.name')) AS `name` from `jtest`.`jemp` where (`jtest`.`jemp`.`g` > 2) 1 row in set (0.00 sec)这类似于MySQL
->
在相同情况下扩展运算符的方式。JSON_KEYS(json_doc[,path])
以JSON数组的形式返回JSON对象的顶级值中的键,或者,如果提供了
path
参数,则返回所选路径中的顶级键。NULL
如果任何参数是NULL
,则返回,该json_doc
参数不是对象,或者path
如果给定,则不定位对象。如果json_doc
参数不是有效的JSON文档,或者path
参数不是有效的路径表达式或包含*
或**
通配符,则会发生错误。如果所选对象为空,则结果数组为空。如果顶级值具有嵌套的子对象,则返回值不包含来自那些子对象的键。
mysql>
SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}'); +--------------------------------------- + | JSON_KEYS('{"a": 1, "b": {"c": 30}}') | +--------------------------------------- + | ["a", "b"] | +--------------------------------------- + mysql>SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b'); +---------------------------------------------- + | JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b') | +---------------------------------------------- + | ["c"] | +---------------------------------------------- +JSON_OVERLAPS(json_doc1,json_doc2)
比较两个JSON文档。如果两个文档具有共同的任何键值对或数组元素,则返回true(1)。如果两个参数均为标量,则该函数将执行简单的相等性测试。
此功能与相对应
JSON_CONTAINS()
,后者要求要搜索的数组的所有元素都出现在要搜索的数组中。因此,JSON_CONTAINS()
在执行AND
搜索键的同时JSON_OVERLAPS()
执行OR
操作。可以使用多值索引来优化在子句中
InnoDB
使用的表的JSON列查询。多值索引,提供详细信息和示例。JSON_OVERLAPS()
WHERE
当两个比较两个数组时,
JSON_OVERLAPS()
如果它们共享一个或多个数组元素,则返回true;否则,返回false:mysql>
SELECT JSON_OVERLAPS("[1,3,5,7]", "[2,5,7]"); +--------------------------------------- + | JSON_OVERLAPS("[1,3,5,7]", "[2,5,7]") | +--------------------------------------- + | 1 | +--------------------------------------- + 1 row in set (0.00 sec) mysql>SELECT JSON_OVERLAPS("[1,3,5,7]", "[2,6,7]"); +--------------------------------------- + | JSON_OVERLAPS("[1,3,5,7]", "[2,6,7]") | +--------------------------------------- + | 1 | +--------------------------------------- + 1 row in set (0.00 sec) mysql>SELECT JSON_OVERLAPS("[1,3,5,7]", "[2,6,8]"); +--------------------------------------- + | JSON_OVERLAPS("[1,3,5,7]", "[2,6,8]") | +--------------------------------------- + | 0 | +--------------------------------------- + 1 row in set (0.00 sec)部分匹配被视为不匹配,如下所示:
mysql>
SELECT JSON_OVERLAPS('[[1,2],[3,4],5]', '[1,[2,3],[4,5]]'); +----------------------------------------------------- + | JSON_OVERLAPS('[[1,2],[3,4],5]', '[1,[2,3],[4,5]]') | +----------------------------------------------------- + | 0 | +----------------------------------------------------- + 1 row in set (0.00 sec)比较对象时,如果它们至少有一个共同的键值对,则结果为true。
mysql>
SELECT JSON_OVERLAPS('{"a":1,"b":10,"d":10}', '{"c":1,"e":10,"f":1,"d":10}'); +----------------------------------------------------------------------- + | JSON_OVERLAPS('{"a":1,"b":10,"d":10}', '{"c":1,"e":10,"f":1,"d":10}') | +----------------------------------------------------------------------- + | 1 | +----------------------------------------------------------------------- + 1 row in set (0.00 sec) mysql>SELECT JSON_OVERLAPS('{"a":1,"b":10,"d":10}', '{"a":5,"e":10,"f":1,"d":20}'); +----------------------------------------------------------------------- + | JSON_OVERLAPS('{"a":1,"b":10,"d":10}', '{"a":5,"e":10,"f":1,"d":20}') | +----------------------------------------------------------------------- + | 0 | +----------------------------------------------------------------------- + 1 row in set (0.00 sec)如果将两个标量用作函数的参数,请
JSON_OVERLAPS()
执行简单的相等性测试:mysql>
SELECT JSON_OVERLAPS('5', '5'); +------------------------- + | JSON_OVERLAPS('5', '5') | +------------------------- + | 1 | +------------------------- + 1 row in set (0.00 sec) mysql>SELECT JSON_OVERLAPS('5', '6'); +------------------------- + | JSON_OVERLAPS('5', '6') | +------------------------- + | 0 | +------------------------- + 1 row in set (0.00 sec)将标量与数组进行比较时,请
JSON_OVERLAPS()
尝试将标量视为数组元素。在此示例中,第二个参数6
解释为[6]
,如下所示:mysql>
SELECT JSON_OVERLAPS('[4,5,6,7]', '6'); +--------------------------------- + | JSON_OVERLAPS('[4,5,6,7]', '6') | +--------------------------------- + | 1 | +--------------------------------- + 1 row in set (0.00 sec)该函数不执行类型转换:
mysql>
SELECT JSON_OVERLAPS('[4,5,"6",7]', '6'); +----------------------------------- + | JSON_OVERLAPS('[4,5,"6",7]', '6') | +----------------------------------- + | 0 | +----------------------------------- + 1 row in set (0.00 sec) mysql>SELECT JSON_OVERLAPS('[4,5,6,7]', '"6"'); +----------------------------------- + | JSON_OVERLAPS('[4,5,6,7]', '"6"') | +----------------------------------- + | 0 | +----------------------------------- + 1 row in set (0.00 sec)JSON_OVERLAPS()
已在MySQL 8.0.17中添加。JSON_SEARCH(
json_doc
,one_or_all
,search_str
[,escape_char
[,path
]...])返回JSON文档中给定字符串的路径。
NULL
如果任何一个,或参数为json_doc
,则返回;文件内不存在;或找不到。如果参数不是有效的JSON文档,任何参数不是有效的路径表达式,不是或或不是常数表达式,都会发生错误。search_str
path
NULL
path
search_str
json_doc
path
one_or_all
'one'
'all'
escape_char
该
one_or_all
参数影响搜索,如下所示:'one'
:搜索在第一个匹配项后终止,并返回一个路径字符串。未定义首先考虑哪个匹配。'all'
:搜索将返回所有匹配的路径字符串,因此不包括重复的路径。如果有多个字符串,它们将自动包装为一个数组。数组元素的顺序是不确定的。
在
search_str
搜索字符串参数中,%
和_
字符与LIKE
运算符的作用相同:%
匹配任意数量的字符(包括零个字符),并且_
恰好匹配一个字符。要在搜索字符串中指定文字
%
或_
字符,请在其前面加上转义字符。默认值是\
,如果escape_char
参数丢失或NULL
。否则,escape_char
必须为空或一个字符的常量。有关匹配和转义字符行为的详细信息,请参阅的说明
LIKE
在 12.7.1节,“字符串比较函数和操作符”。对于转义字符处理,与LIKE
行为的区别在于,转义字符JSON_SEARCH()
必须在编译时而不是仅在执行时求值为常数。例如,如果JSON_SEARCH()
在准备好的语句中escape_char
使用并且?
参数使用参数提供,则参数值在执行时可能是恒定的,但在编译时却不是。mysql>
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; mysql>SELECT JSON_SEARCH(@j, 'one', 'abc'); +------------------------------- + | JSON_SEARCH(@j, 'one', 'abc') | +------------------------------- + | "$[0]" | +------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', 'abc'); +------------------------------- + | JSON_SEARCH(@j, 'all', 'abc') | +------------------------------- + | ["$[0]", "$[2].x"] | +------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', 'ghi'); +------------------------------- + | JSON_SEARCH(@j, 'all', 'ghi') | +------------------------------- + | NULL | +------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '10'); +------------------------------ + | JSON_SEARCH(@j, 'all', '10') | +------------------------------ + | "$[1][0].k" | +------------------------------ + mysql>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$'); +----------------------------------------- + | JSON_SEARCH(@j, 'all', '10', NULL, '$') | +----------------------------------------- + | "$[1][0].k" | +----------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*]'); +-------------------------------------------- + | JSON_SEARCH(@j, 'all', '10', NULL, '$[*]') | +-------------------------------------------- + | "$[1][0].k" | +-------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$**.k'); +--------------------------------------------- + | JSON_SEARCH(@j, 'all', '10', NULL, '$**.k') | +--------------------------------------------- + | "$[1][0].k" | +--------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*][0].k'); +------------------------------------------------- + | JSON_SEARCH(@j, 'all', '10', NULL, '$[*][0].k') | +------------------------------------------------- + | "$[1][0].k" | +------------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1]'); +-------------------------------------------- + | JSON_SEARCH(@j, 'all', '10', NULL, '$[1]') | +-------------------------------------------- + | "$[1][0].k" | +-------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1][0]'); +----------------------------------------------- + | JSON_SEARCH(@j, 'all', '10', NULL, '$[1][0]') | +----------------------------------------------- + | "$[1][0].k" | +----------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', 'abc', NULL, '$[2]'); +--------------------------------------------- + | JSON_SEARCH(@j, 'all', 'abc', NULL, '$[2]') | +--------------------------------------------- + | "$[2].x" | +--------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '%a%'); +------------------------------- + | JSON_SEARCH(@j, 'all', '%a%') | +------------------------------- + | ["$[0]", "$[2].x"] | +------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '%b%'); +------------------------------- + | JSON_SEARCH(@j, 'all', '%b%') | +------------------------------- + | ["$[0]", "$[2].x", "$[3].y"] | +------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[0]'); +--------------------------------------------- + | JSON_SEARCH(@j, 'all', '%b%', NULL, '$[0]') | +--------------------------------------------- + | "$[0]" | +--------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[2]'); +--------------------------------------------- + | JSON_SEARCH(@j, 'all', '%b%', NULL, '$[2]') | +--------------------------------------------- + | "$[2].x" | +--------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[1]'); +--------------------------------------------- + | JSON_SEARCH(@j, 'all', '%b%', NULL, '$[1]') | +--------------------------------------------- + | NULL | +--------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[1]'); +------------------------------------------- + | JSON_SEARCH(@j, 'all', '%b%', '', '$[1]') | +------------------------------------------- + | NULL | +------------------------------------------- + mysql>SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[3]'); +------------------------------------------- + | JSON_SEARCH(@j, 'all', '%b%', '', '$[3]') | +------------------------------------------- + | "$[3].y" | +------------------------------------------- +有关MySQL支持JSON的路径语法,包括有关通配符运营规则的详细信息
*
,并**
请参阅 JSON路径语法。value MEMBER OF(json_array)
如果
value
是的元素json_array
,则返回true(1),否则返回false(0)。value
必须是标量或JSON文档;如果它是标量,则运算符尝试将其视为JSON数组的元素。可以使用多值索引优化在子句中
MEMBER OF()
的InnoDB
表的 JSON列上使用的查询WHERE
。有关详细信息和示例,请参见“多值索引”。简单标量被视为数组值,如下所示:
mysql>
SELECT 17 MEMBER OF('[23, "abc", 17, "ab", 10]'); +------------------------------------------- + | 17 MEMBER OF('[23, "abc", 17, "ab", 10]') | +------------------------------------------- + | 1 | +------------------------------------------- + 1 row in set (0.00 sec) mysql>SELECT 'ab' MEMBER OF('[23, "abc", 17, "ab", 10]'); +--------------------------------------------- + | 'ab' MEMBER OF('[23, "abc", 17, "ab", 10]') | +--------------------------------------------- + | 1 | +--------------------------------------------- + 1 row in set (0.00 sec)数组元素值的部分匹配不匹配:
mysql>
SELECT 7 MEMBER OF('[23, "abc", 17, "ab", 10]'); +------------------------------------------ + | 7 MEMBER OF('[23, "abc", 17, "ab", 10]') | +------------------------------------------ + | 0 | +------------------------------------------ + 1 row in set (0.00 sec)mysql>
SELECT 'a' MEMBER OF('[23, "abc", 17, "ab", 10]'); +-------------------------------------------- + | 'a' MEMBER OF('[23, "abc", 17, "ab", 10]') | +-------------------------------------------- + | 0 | +-------------------------------------------- + 1 row in set (0.00 sec)不执行与字符串类型之间的转换:
mysql>
SELECT -> 17 MEMBER OF('[23, "abc", "17", "ab", 10]'), -> "17" MEMBER OF('[23, "abc", 17, "ab", 10]')\G *************************** 1. row *************************** 17 MEMBER OF('[23, "abc", "17", "ab", 10]') : 0 "17" MEMBER OF('[23, "abc", 17, "ab", 10]') : 0 1 row in set (0.00 sec)若要将此运算符与本身为数组的值一起使用,必须将其显式转换为JSON数组。您可以使用
CAST(... AS JSON)
:mysql>
SELECT CAST('[4,5]'AS JSON) MEMBER OF('[[3,4],[4,5]]'); +-------------------------------------------------- + | CAST('[4,5]' AS JSON) MEMBER OF('[[3,4],[4,5]]') | +-------------------------------------------------- + | 1 | +-------------------------------------------------- + 1 row in set (0.00 sec)也可以使用
JSON_ARRAY()
函数执行必要的强制转换,如下所示:mysql>
SELECT JSON_ARRAY(4,5) MEMBER OF('[[3,4],[4,5]]'); +-------------------------------------------- + | JSON_ARRAY(4,5) MEMBER OF('[[3,4],[4,5]]') | +-------------------------------------------- + | 1 | +-------------------------------------------- + 1 row in set (0.00 sec)必须使用
CAST(... AS JSON)
或将任何用作测试值或出现在目标数组中的JSON对象强制为正确的类型JSON_OBJECT()
。此外,包含JSON对象的目标数组本身必须使用强制转换JSON_ARRAY
。下面的语句序列演示了这一点:mysql>
SET @a = CAST('{"a":1}'AS JSON); Query OK, 0 rows affected (0.00 sec) mysql>SET @b = JSON_OBJECT("b", 2); Query OK, 0 rows affected (0.00 sec) mysql>SET @c = JSON_ARRAY(17, @b, "abc", @a, 23); Query OK, 0 rows affected (0.00 sec) mysql>SELECT @a MEMBER OF(@c), @b MEMBER OF(@c); +------------------ +------------------ + | @a MEMBER OF(@c) | @b MEMBER OF(@c) | +------------------ +------------------ + | 1 | 1 | +------------------ +------------------ + 1 row in set (0.00 sec)该
MEMBER OF()
操作符是在MySQL 8.0.17中添加的。