搜索 JSON 值

Exisi 2023-01-23 20:08:01
Categories: Tags:

函数

说明

JSON_CONTAINS()

JSON 文档是否在路径处包含特定对象

JSON_CONTAINS_PATH()

JSON 文档是否在路径上包含任何数据

JSON_EXTRACT()

JSON 文档返回数据

JSON_KEYS()

来自 JSON 文档的密钥数组

JSON_OVERLAPS()

比较两个 JSON 文档,如果这些文档具有任何共同的键值对或数组元素,则返回 TRUE 1),否则返回 FALSE 0

JSON_SEARCH()

JSON 文档中的值的路径

JSON_VALUE()

从提供的路径所指向的位置的 JSON 文档中提取值;将此值返回为 VARCHAR512) 或指定类型

 

 

JSON_CONTAINS(target, candidate[, path])

  • 通过返回 1 0 来指示给定的候选 JSON 文档是否包含在目标 JSON 文档中,或者 - 如果提供了路径参数 - 是否在目标内的特定路径中找到候选。

 

  • 如果任何参数是 ,或者路径参数未标识目标文档的一部分,则返回。

 

  • 如果目标或候选对象不是有效的 JSON 文档,或者路径参数不是有效的路径表达式或包含通配符或通配符,则会发生错误

 

  • 以下规则定义了包含:
    • 当且仅当它们可比较且相等时,候选标量包含在目标标量中。如果两个标量值具有相同的 JSON_TYPE() 类型,则它们是可比较的,除了类型的值也可以相互比较。整数小数
    • 当且仅当候选数组中的每个元素都包含在目标的某个元素中时,候选数组才包含在目标数组中。
    • 当且仅当候选包含在目标的某个元素中时,候选非数组才包含在目标数组中。
    • 候选对象包含在目标对象中当且仅当对于候选对象中的每个键在目标中存在同名键并且与候选键关联的值包含在与目标键关联的值中。

 

否则,候选值不包含在目标文档中

 

  • MySQL 8.0.17 开始,使用 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 文档是否包含给定路径或路径中的数据。如果任何参数是 则返回。如果 json_doc 参数不是有效的 JSON 文档,任何路径参数都不是有效的路径表达式,或者 one_or_all 不是或,则会发生错误或者 NULL NULL '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 文档返回数据,从路径参数匹配的文档部分中选择。如果任何参数是或没有路径在文档中定位一个值,则返回。如果 json_doc 参数不是有效的 JSON 文档或任何路径参数不是有效的路径表达式,则会发生错误。NULLNULL

 

  • 返回值由路径参数匹配的所有值组成。如果这些参数有可能返回多个值,则匹配的值将按照与生成它们的路径相对应的顺序自动包装为数组。否则,返回值为单个匹配值

示例

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 jemp ADD COLUMN n INT;

Query OK, 0 rows affected (0.68 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> UPDATE jemp SET n=1 WHERE 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 jemp WHERE 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 数组值,如下所示:

示例

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 tj10 WHERE 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)

 

  • 支持嵌套数组。表达式 using 的计算结果就像在目标 JSON 文档中找不到匹配的键一样,如下所示: ->NULL

示例

mysql> SELECT * FROM tj10 WHERE 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

  • 这是一个改进的、不引用的提取运算符。而 -> 运算符只是提取一个值,而 ->> 运算符还取消引用提取的结果

 

  • 以下三个表达式返回相同的值:

 

  • JSON_UNQUOTE( JSON_EXTRACT(column, path) )
  • JSON_UNQUOTE(column -> path)
  • column->>path

 

  • 运算符可以在任何允许的地方使用。这包括(但不限于)列表、子句和子句。 ->>JSON_UNQUOTE(JSON_EXTRACT())SELECTWHEREHAVINGORDER BYGROUP BY
  • 接下来的几条语句演示了与 mysql 客户端中其他表达式的一些运算符等价:->>

示例

mysql> SELECT * FROM jemp WHERE 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 jemp WHERE g > 2;

+----------+

|name       |

+----------+

|"Barney" |

|"Betty"   |

+----------+

2 rows in set (0.00 sec)

mysql> SELECT JSON_UNQUOTE(c->'$.name') AS name     

->        FROM jemp WHERE g > 2;

+--------+

|name   |

+--------+

|Barney |

|Betty   |

+--------+

2 rows in set (0.00 sec)

mysql> SELECT c->>'$.name' AS name     

->        FROM jemp WHERE g > 2;

+--------+

|name    |

+--------+

|Barney |

|Betty   |

+--------+

2 rows in set (0.00 sec)

 

  • 此运算符也可以与 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,"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 jemp WHERE 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 数组返回,或者,如果给出了路径参数,则返回所选路径中的顶级键。如果任何参数是 ,则返回 json_doc 参数不是对象,或者路径(如果给定)未找到对象。如果 json_doc 参数不是有效的 JSON 文档或 path 参数不是有效的路径表达式或包含或通配符,则会发生错误。NULLNULL***

 

  • 如果所选对象为空,则结果数组为空。如果顶级值具有嵌套的子对象,则返回值不包括来自这些子对象的键。

示例

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() ANDJSON_OVERLAPS()

 

  • 在子句中使用的 InnoDB 表的 JSON 列的查询可以使用多值索引进行优化。多值索引,提供详细信息和示例。 JSON_OVERLAPS()WHERE

 

  • 比较两个数组时,如果它们共享一个或多个数组元素,则返回 true,否则返回 falseJSON_OVERLAPS()

示例

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)

 

  • 比较对象时,如果它们至少有一个共同的键值对,则结果为真。

示例

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() was added in MySQL 8.0.17.

 

 

 

JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])

  • 返回 JSON 文档中给定字符串的路径。如果 json_docsearch_str 或路径参数中的任何一个是 ; 则返回文档中不存在路径;或 search_str 未找到。如果 json_doc 参数不是有效的 JSON 文档、任何路径参数不是有效的路径表达式、 one_or_all 不是 or escape_char 不是常量表达式,则会发生错误。 NULL NULL'一个''全部'

 

  • one_or_all 参数对搜索的影响如下:

 

  • 'one':搜索在第一次匹配后终止并返回一个路径字符串。首先考虑哪个匹配是未定义的。
  • 'all':搜索返回所有匹配的路径字符串,这样不包括重复的路径。如果有多个字符串,它们会自动包装为一个数组。数组元素的顺序未定义。

 

  • search_str 搜索字符串参数中,and 字符与 LIKE 运算符一样工作:匹配任意数量的字符(包括零个字符),并且只匹配一个字符。 %_%_

 

  • 要在搜索字符串中指定文字或字符,请在其前面加上转义字符。默认值为缺少 escape_char 参数或 .否则,escape_char 必须是一个为空或一个字符的常量。 %_\空值

 

  • 对于转义字符处理,与 LIKE 行为的不同之处在于 JSON_SEARCH() 的转义字符必须在编译时计算为常量,而不仅仅是在执行时。例如,如果在准备好的语句中使用 JSON_SEARCH() 并且使用参数提供了 escape_char 参数,则参数值在执行时可能是常量,但在编译时不是。

  • search_str path 总是以 utf8mb4 字符串的形式插入,无论它们的实际编码如何。这是一个已知问题,已在 MySQL 8.0.24 中修复(错误 #32449181)。

 

 

 

JSON_VALUE(json_doc, path)

  • 从指定文档中给定路径的 JSON 文档中提取值,并返回提取的值,可选择将其转换为所需的类型。

语法

JSON_VALUE(json_doc, path [RETURNING type] [on_empty] [on_error])

on_empty:

{NULL | ERROR | DEFAULT value} ON EMPTY

on_error:

{NULL | ERROR | DEFAULT value} ON ERROR

 

参数

描述

json_doc

一个有效的 JSON 文档。

path

指向文档中某个位置的 JSON 路径。这必须是字符串文字值

type

FLOAT

DOUBLE

DECIMAL

SIGNED

UNSIGNED

DATE

TIME

DATETIME

YEAR (MySQL 8.0.22 and later) 不支持一位或两位数字的 YEAR 值。

CHAR

JSON

on_empty

如果指定,则确定在给定路径上找不到数据时的行为;此子句采用以下值之一: JSON_VALUE()

  • NULL ON EMPTY:函数返回;这是默认行为。 NULLON
  • DEFAULT value ON EMPTY:返回提供的值。值的类型必须与返回类型匹配。
  • ERROR ON EMPTY:函数抛出错误。

 

如果使用,on_error 会在发生错误时采用以下值之一以及相应的结果,如下所示:

  • NULL ON ERROR:返回;如果不使用子句,这是默认行为。 JSON_VALUE()NULLON 错误
  • DEFAULT value ON ERROR:这是返回的值;它的值必须与返回类型的值匹配。
  • ERROR ON ERROR:抛出错误。

 

如果使用 ON EMPTY,则必须在任何子句之前。以错误的顺序指定它们会导致语法错误。开启错误

 

错误处理。一般来说,错误的处理方式如下: JSON_VALUE()

  • 检查所有 JSON 输入(文档和路径)的有效性。如果其中任何一个无效,则在不触发子句的情况下引发 SQL 错误。开启错误
  • 只要发生以下任何事件,就会触发 ON ERROR
  • 尝试提取对象或数组,例如从解析到 JSON 文档中多个位置的路径产生的对象或数组
  • 转换错误,例如尝试转换为值 'asdf'UNSIGNED
  • 截断值
  • 即使指定了 或 ,转换错误总是会触发警告。 NULL ON ERRORDEFAULT ... ON ERROR
  • 当源 JSON 文档 (expr) 在指定位置(路径)不包含数据时,将触发该子句。空

 

  • JSON_VALUE() 简化了在 JSON 列上创建索引的过程,因为在许多情况下无需创建生成的列然后在生成的列上创建索引。您可以在创建具有 JSON 列的表时执行此操作,方法是在使用对该列进行操作的表达式上创建索引(使用与该列中的值匹配的路径),如下所示:t1JSON_VALUE()

示例

CREATE TABLE t1(

j JSON, INDEX i1 ( (JSON_VALUE(j, '$.id' RETURNING UNSIGNED)) )

);

 

  • 以下 EXPLAIN 输出显示针对在子句中使用索引表达式的查询使用了由此创建的索引:t1WHERE

示例

mysql> EXPLAIN SELECT * FROM t1     

-> WHERE JSON_VALUE(j, '$.id' RETURNING UNSIGNED) = 123\G

***************************1. row ***************************

                       id : 1
       select_type : SIMPLE
   
             table : t1
  
       partitions : NULL
      
           type : ref
   possible_keys : i1
       
           key : i1
     
       key_len : 9
    
               ref : const
       
          rows : 1
   
         filtered : 100.00
      
         Extra : NULL

 

  • 这与在生成的列上创建具有索引的表的效果大致相同

示例

CREATE TABLE t2 (

j JSON,

g INT GENERATED ALWAYS AS (j->"$.id"),

INDEX i1 (j)

);

 

  • 针对该表的查询的 EXPLAIN 输出(引用生成的列)显示该索引的使用方式与上一个针对表的查询相同:t1

示例

mysql> EXPLAIN SELECT * FROM t2 WHERE g = 123\G

***************************1. row ***************************

                        id : 1
 
      select_type : SIMPLE
    
             table : t2
  
        partitions : NULL
       
           type : ref
    possible_keys : i1
      
             key : i1
   
         key_len : 5
         
          ref : const
        
         rows : 1
  
          filtered : 100.00
      
         Extra : NULL

JSON_VALUE() MySQL 8.0.21 中引入。

 

 

 

value MEMBER OF(json_array)

  • 如果 value json_array 的元素,则返回 true (1),否则返回 false (0) value 必须是标量或 JSON 文档

 

  • 如果它是标量,则运算符会尝试将其视为 JSON 数组的元素。

 

  • 在子句中使用 InnoDB 表的 JSON 列的查询可以使用多值索引进行优化

 

  • 简单的标量被视为数组值,如下所示:

示例

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)

 

  • 任何用作要测试的值或出现在目标数组中的 JSON 对象都必须使用 JSON_OBJECT() 强制转换为正确的类型。此外,包含 JSON 对象的目标数组本身必须使用 .这在以下语句序列中得到了证明: CAST(... AS 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 中添加。

 

 

 

来自 <https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains>