All Products
Search
Document Center

AnalyticDB:JSON functions

Last Updated:Mar 28, 2026

AnalyticDB for MySQL supports the following JSON functions for querying and manipulating JSON data. Some functions also use JSON array indexes to speed up lookups and avoid full table scans.

Version requirements: Some functions require a specific cluster version. To check or update the minor version of your cluster, go to the Cluster Information page in the AnalyticDB for MySQL console and find the Configuration Information section.

Functions at a glance

FunctionDescriptionVersion
JSON_ARRAY_CONTAINSChecks whether a JSON array contains a valueAny
JSON_ARRAY_LENGTHReturns the number of elements in a JSON arrayAny
JSON_CONTAINSChecks whether a JSON document contains a value, with optional JSON array index support3.1.5.0+
JSON_CONTAINS_PATHChecks whether a JSON document contains one or all of the specified paths3.1.5.0+
JSON_EXTRACTExtracts a value from a JSON document at the specified pathAny
JSON_KEYSReturns all keys of a JSON object at a given pathAny
JSON_OVERLAPSChecks whether a JSON document contains any of the specified elements3.1.10.6+
JSON_REMOVERemoves one or more elements from a JSON document3.1.10.0+
JSON_SETInserts or updates values in a JSON document3.2.2.8+
JSON_SIZEReturns the number of keys or elements in a JSON object or arrayAny
JSON_UNQUOTERemoves outer double quotes from a JSON string and unescapes escape sequences3.1.5.0+

JSON_ARRAY_CONTAINS

json_array_contains(json, value)

Returns 1 if the JSON array contains value, or 0 if it does not.

Parameters:

ParameterTypeRequired
jsonSTRING or JSONYes
valueNumeric, STRING, or BOOLEANYes

Return type: BOOLEAN

Example:

Check whether [1, 2, 3] contains 2:

SELECT json_array_contains('[1, 2, 3]', 2);
+-------------------------------------+
| json_array_contains('[1, 2, 3]', 2) |
+-------------------------------------+
|                1                    |
+-------------------------------------+

JSON_ARRAY_LENGTH

json_array_length(json)

Returns the number of elements in a JSON array.

Parameters:

ParameterTypeRequired
jsonSTRING or JSONYes

Return type: BIGINT

Example:

Get the length of [1, 2, 3]:

SELECT json_array_length('[1, 2, 3]');
+--------------------------------+
| json_array_length('[1, 2, 3]') |
+--------------------------------+
|                 3              |
+--------------------------------+

JSON_CONTAINS

Important

Requires AnalyticDB for MySQL version 3.1.5.0 or later. The index-optimized form requires version 3.1.10.6 or later.

JSON_CONTAINS checks whether a JSON document contains a given value. It has two forms:

  • Standard form — works on any JSON data

  • Index-optimized form — uses a JSON array index to avoid full table scans

Standard form

json_contains(target, candidate[, json_path])
  • If json_path is specified, checks whether the value at that path equals candidate.

  • If json_path is omitted, checks whether target contains candidate.

Returns 1 for true and 0 for false.

Parameters:

ParameterTypeRequired
targetJSONYes
candidateJSONYes
json_pathJSONPATHNo

Return type: BOOLEAN

Containment rules:

  • Primitive types (NUMBER, BOOLEAN, STRING, NULL): target contains candidate if they are equal.

  • Both are JSON arrays: target contains candidate if every element of candidate is also in target.

  • `target` is an array, `candidate` is not: target contains candidate if candidate is an element of target.

  • Both are JSON objects: target contains candidate if every key of candidate exists in target, and each value in candidate is contained in the corresponding value of target.

Examples:

Check whether the value at $.a equals 1:

SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '1', '$.a') as result;
+--------+
| result |
+--------+
|      1 |
+--------+

Check whether the value at $.b equals 1:

SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '1', '$.b') as result;
+--------+
| result |
+--------+
|      0 |
+--------+

Check whether the top-level document contains {"d": 4}:

SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '{"d": 4}') as result;
+--------+
| result |
+--------+
|      0 |
+--------+

The result is 0 because {"d": 4} is nested under $.c, not at the root level.

Index-optimized form

json_contains(json_path, cast('[candidate1, candidate2, ...]' as json))

Checks whether a JSON column contains all of the specified elements. Use this form when a JSON array index is defined on the column — it avoids full table scans.

Important

Before using this form, create a JSON array index on the JSON column. To verify that the index is used, prepend EXPLAIN to your query. If the execution plan does not include the ScanFilterProject operator, the index is active.

Parameters:

ParameterTypeRequired
json_pathJSON column referenceYes
Candidate arrayJSON (all elements must share the same data type: numeric or STRING)Yes

Return type: VARCHAR

Examples:

Check whether column vj contains both CP-018673 and CP-018671:

SELECT json_contains(vj, cast('["CP-018673","CP-018671"]' AS json)) FROM json_test;
+------------------------------------------------------------+
|json_contains(vj, cast('["CP-018673","CP-018671"]' AS json))|
+------------------------------------------------------------+
|                    0                                       |
+------------------------------------------------------------+
|                    0                                       |
+------------------------------------------------------------+
|                    1                                       |
+------------------------------------------------------------+
|                    0                                       |
+------------------------------------------------------------+
|                    0                                       |
+------------------------------------------------------------+

Check whether column vj contains CP-018673, 1, and 2:

SELECT json_contains(vj, cast('["CP-018673",1,2]' AS json)) FROM json_test;
+------------------------------------------------------------+
|json_contains(vj, cast('["CP-018673","CP-018671"]' AS json))|
+------------------------------------------------------------+
|                    0                                       |
+------------------------------------------------------------+
|                    1                                       |
+------------------------------------------------------------+
|                    1                                       |
+------------------------------------------------------------+
|                    0                                       |
+------------------------------------------------------------+
|                    1                                       |
+------------------------------------------------------------+

JSON_CONTAINS_PATH

json_contains_path(json, one_or_all, json_path[, json_path, ...])
Important

Requires AnalyticDB for MySQL version 3.1.5.0 or later.

Checks whether a JSON document contains values at the specified paths.

  • 'one': returns 1 if at least one of the paths exists in the document.

  • 'all': returns 1 only if all paths exist in the document.

Parameters:

ParameterTypeRequired
jsonJSONYes
one_or_allVARCHAR — 'one' or 'all' (case-insensitive)Yes
json_pathPath expression (one or more)Yes

Return type: BOOLEAN

Examples:

Check whether the document contains at least one of $.a and $.e:

SELECT json_contains_path(json '{"a": 1, "b": 2, "c": {"d": 4}}', 'one', '$.a', '$.e') AS result;
+--------+
| result |
+--------+
|      1 |
+--------+

Check whether the document contains both $.a and $.e:

SELECT json_contains_path(json '{"a": 1, "b": 2, "c": {"d": 4}}', 'all', '$.a', '$.e') AS result;
+--------+
| result |
+--------+
|      0 |
+--------+

JSON_EXTRACT

json_extract(json, json_path)

Returns the value at json_path in a JSON document.

If a key contains special characters such as $ or ., use bracket notation: '$["key"]'. For example, to access the key $date, use '$["$date"]'.

Important
  • Return values of JSON_EXTRACT do not support ORDER BY.

  • To use the return value of JSON_EXTRACT as input for JSON_UNQUOTE, first cast it to VARCHAR using CAST AS VARCHAR.

Parameters:

ParameterTypeRequired
jsonSTRING or JSONYes
json_pathJSONPATHYes

Return type: JSON

Examples:

Extract the first element of the array [10, 20, [30, 40]]:

SELECT json_extract('[10, 20, [30, 40]]', '$[0]');
+--------------------------------------------+
| json_extract('[10, 20, [30, 40]]', '$[0]') |
+--------------------------------------------+
|                     10                     |
+--------------------------------------------+

Extract the value of a key that contains a special character ($date):

SELECT JSON_EXTRACT('{"id":"1","$date":"12345"}', '$["$date"]');
+---------------------------------------------------------+
|JSON_EXTRACT('{"id":"1","$date":"12345"}', '$["$date"]') |
+---------------------------------------------------------+
|                       "12345"                           |
+---------------------------------------------------------+

JSON_KEYS

json_keys(json[, json_path])

Returns all keys of a JSON object. If json_path is specified, returns keys at that path. Without json_path, returns keys at the root ($).

The json parameter must be of the JSON type. Construct it with:

  • JSON literal: json '{"a": 1}'

  • CAST function: CAST('{"a": 1}' AS json)

Parameters:

ParameterTypeRequired
jsonJSONYes
json_pathPath expressionNo

Return type: JSON array

Examples:

Get all keys in the nested object at $.b:

SELECT json_keys(CAST('{"a": 1, "b": {"c": 30}}' AS json), '$.b');
+-----------------------------------------------------------+
| json_keys(CAST('{"a": 1, "b": {"c": 30}}' AS json),'$.b') |
+-----------------------------------------------------------+
|                           ["c"]                           |
+-----------------------------------------------------------+

Get all top-level keys:

SELECT JSON_KEYS(json '{"a": 1, "b": {"c": 30}}');
+--------------------------------------------+
| JSON_KEYS(json '{"a": 1, "b": {"c": 30}}') |
+--------------------------------------------+
|             ["a","b"]                      |
+--------------------------------------------+

JSON_OVERLAPS

json_overlaps(json, cast('[candidate1, candidate2, ...]' as json))
Important

Requires AnalyticDB for MySQL version 3.1.10.6 or later. Before using this function, create a JSON array index on the JSON column. To verify that the index is used, prepend EXPLAIN to your query. If the execution plan does not include the ScanFilterProject operator, the index is active.

Checks whether a JSON document contains any of the specified elements. Use this function in WHERE clauses to filter rows where a JSON array column overlaps with a given set of values.

All candidate values must share the same data type (numeric or STRING).

Parameters:

ParameterTypeRequired
jsonJSON columnYes
Candidate arrayJSON (all elements must share the same data type)Yes

Return type: VARCHAR

Examples:

Return all rows where column vj contains CP-018673:

SELECT * FROM json_test WHERE json_overlaps(vj, cast('["CP-018673"]' AS json));
+-----+----------------------------------------------------------------------------+
|  id |   vj                                                                       |
+-----+----------------------------------------------------------------------------+
|  2  | ["CP-018673", 1, false]                                                    |
+-----+----------------------------------------------------------------------------+
|  3  | ["CP-018673", 1, false, {"a": 1}]                                          |
+-----+----------------------------------------------------------------------------+
|  5  | ["CP-018673","CP-018671","CP-018672","CP-018670","CP-018669","CP-018668"]  |
+-----+----------------------------------------------------------------------------+

Return all rows where column vj contains any of 1, 2, or 3:

SELECT * FROM json_test WHERE json_overlaps(vj, cast('[1,2,3]' AS json));
+-----+-------------------------------------+
|  id |                 vj                  |
+-----+-------------------------------------+
|  1  | [1,2,3]                             |
+-----+-------------------------------------+
|  2  | ["CP-018673", 1, false]             |
+-----+-------------------------------------+
|  3  | ["CP-018673", 1, false, {"a": 1}]   |
+-----+-------------------------------------+

JSON_REMOVE

json_remove(json, json_path)
json_remove(json, array[json_path, json_path, ...])
Important

Requires AnalyticDB for MySQL version 3.1.10.0 or later.

Removes one or more elements from a JSON document and returns the updated document as a string. To remove multiple elements in one call, pass an array of paths.

Parameters:

ParameterTypeRequired
jsonVARCHAR (JSON format)Yes
json_pathVARCHAR (JSON path) — single path or array of pathsYes

Return type: VARCHAR

Examples:

Remove the element at $.glossary.GlossDiv:

SELECT json_remove(
  '{
      "glossary": {
          "title": "example glossary",
          "GlossDiv": {
              "title": "S",
              "GlossList": {
                  "GlossEntry": {
                      "ID": "SGML",
                      "SortAs": "SGML",
                      "GlossTerm": "Standard Generalized Markup Language",
                      "Acronym": "SGML",
                      "Abbrev": "ISO 8879:1986",
                      "GlossDef": {
                          "para": "A meta-markup language, used to create markup languages such as DocBook.",
                          "GlossSeeAlso": ["GML", "XML"]
                      },
                      "GlossSee": "markup"
                  }
              }
          }
      }
  }',
  '$.glossary.GlossDiv') a;
{"glossary":{"title":"example glossary"}}

Remove multiple elements at once using an array of paths:

SELECT json_remove(
  '{
      "glossary": {
          "title": "example glossary",
          "GlossDiv": {
              "title": "S",
              "GlossList": {
                  "GlossEntry": {
                      "ID": "SGML",
                      "SortAs": "SGML",
                      "GlossTerm": "Standard Generalized Markup Language",
                      "Acronym": "SGML",
                      "Abbrev": "ISO 8879:1986",
                      "GlossDef": {
                          "para": "A meta-markup language, used to create markup languages such as DocBook.",
                          "GlossSeeAlso": ["GML", "XML"]
                      },
                      "GlossSee": "markup"
                  }
              }
          }
      }
  }',
  array['$.glossary.title', '$.glossary.GlossDiv.title']) a;
{"glossary":{"GlossDiv":{"GlossList":{"GlossEntry":{"GlossTerm":"Standard Generalized Markup Language","GlossSee":"markup","SortAs":"SGML","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"ID":"SGML","Acronym":"SGML","Abbrev":"ISO 8879:1986"}}}}}

JSON_SET

json_set(json, json_path, value[, json_path, value] ...)
Important

Requires AnalyticDB for MySQL version 3.2.2.8 or later.

Inserts or updates one or more values in a JSON document and returns the updated document. Pass multiple json_path, value pairs to update several locations in one call.

Parameters:

ParameterTypeRequired
jsonVARCHAR or JSONYes
json_pathVARCHARYes
valueBOOLEAN, TINYINT, SMALLINT, INT, BIGINT, FLOAT, DOUBLE, DECIMAL, VARCHAR, VARBINARY, DATE, DATETIME, TIMESTAMP, or TIMEYes

Return type: JSON

Behavior:

  • If json or json_path is NULL, returns NULL.

  • If json is not a valid JSON document, or a json_path is not a valid path expression, an exception is thrown.

  • If the path exists, its value is overwritten.

  • If the path does not exist:

    • Points to a JSON object: the value is inserted as a new key.

    • Points to a JSON array index: if empty slots exist before the index, they are filled with NULL before the value is inserted; otherwise, the value is inserted directly.

    • Other cases: an exception is thrown.

Examples:

When json_path is NULL, the function returns NULL:

SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', null, '10');
+------------------------------------------------+
| JSON_SET('{ "a": 1, "b": [2, 3]}', NULL, '10') |
+------------------------------------------------+
| null                                           |
+------------------------------------------------+

When a path points to an array element but is not a valid insertion point, the function returns an error:

SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.b.c', '10');
Failed to execute json_set() for json_path: $.b.c

Update an existing key ($.a) and insert a new key ($.c) in one call:

SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]');
+-----------------------------------------------------------------------+
| JSON_SET('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') |
+-----------------------------------------------------------------------+
| {"a":10,"b":[2,3],"c":"[true, false]"}                                |
+-----------------------------------------------------------------------+

Insert into an array at index 4 (indices 2 and 3 are filled with NULL):

SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.b[4]', '[true, false]');
+----------------------------------------------------------------+
| JSON_SET('{ "a": 1, "b": [2, 3]}',  '$.b[4]', '[true, false]') |
+----------------------------------------------------------------+
| {"a":1,"b":[2,3,null,null,"[true, false]"]}                    |
+----------------------------------------------------------------+

JSON_SIZE

json_size(json, json_path)

Returns the number of keys in a JSON object, or the number of elements in a JSON array, at the specified path.

Returns 0 if json_path does not point to a JSON object or JSON array.

Parameters:

ParameterTypeRequired
jsonSTRING or JSONYes
json_pathJSONPATHYes

Return type: BIGINT

Examples:

Get the size of the JSON object at $.x:

SELECT json_size('{"x":{"a":1, "b": 2}}', '$.x') as result;
+--------+
| result |
+--------+
|      2 |
+--------+

When the path points to a scalar value (not an object or array), the function returns 0:

SELECT json_size('{"x": {"a": 1, "b": 2}}', '$.x.a') as result;
+--------+
| result |
+--------+
|      0 |
+--------+

JSON_UNQUOTE

json_unquote(json_value)
Important

Requires AnalyticDB for MySQL version 3.1.5.0 or later.

Removes the outer double quotes from json_value and unescapes recognized escape sequences. The input is not validated against JSON syntax — any VARCHAR input is processed as-is.

Supported escape sequences:

Escape sequenceOutput
\"" (double quotation mark)
\bBackspace
\fForm feed
\nLine feed
\rCarriage return
\tTab
\\\ (backslash)
\uXXXXUTF-8 character

Parameters:

ParameterTypeRequired
json_valueVARCHARYes

Return type: VARCHAR

Examples:

Remove the outer double quotes from "abc":

SELECT json_unquote('"abc"');
+-----------------------+
| json_unquote('"abc"') |
+-----------------------+
|          abc          |
+-----------------------+

Unescape a tab character and a Unicode code point:

SELECT json_unquote('"\\t\\u0032"');
+------------------------------+
| json_unquote('"\\t\\u0032"') |
+------------------------------+
|               2              |
+------------------------------+

\t is a tab and \u0032 is the character 2, so the result is a tab followed by 2.

JSON path syntax

All path-based functions use the following syntax to address values in a JSON document.

Patterns:

  • $.keyName — access a key in a JSON object

  • $.keyName.nestedKey — access a nested key

  • $[n] — access the n-th element of a JSON array (n is a non-negative integer)

  • $.keyName[n] — access the n-th element of a nested JSON array

Wildcards (* and **) are not supported. Paths such as '$.*', '$.hobbies[*]', '$.address.'`, and `'$.hobbies.' are invalid.

Examples using the following JSON document:

{
    "name": "Alice",
    "age": 25,
    "address": {
        "city": "Hangzhou",
        "zip": "10001"
    },
    "hobbies": ["reading", "swimming", "cycling"]
}
GoalCorrect pathIncorrect path
Access name$.namename
Access city in the nested object$.address.city$.address[0]
Access the first element of hobbies$.hobbies[0]$.hobbies.[0]

Troubleshooting

java.lang.NullPointerException when using JSON_OVERLAPS

This error means the JSON array index has not taken effect. The most common cause is that the BUILD operation did not run after the index was created with an ALTER statement.

If no BUILD task has run:

AnalyticDB for MySQL automatically triggers a BUILD task when specific conditions are met. To run one immediately, trigger a BUILD task manually.

If a BUILD task has run:

Check its status with the following query. A status value of FINISH means the BUILD is complete and the index is active.

SELECT table_name, schema_name, status
FROM INFORMATION_SCHEMA.KEPLER_META_BUILD_TASK
ORDER BY create_time DESC
LIMIT 10;

For more information, see BUILD.

What's next

  • JSON — learn about the JSON data type in AnalyticDB for MySQL

  • JSON indexes — create indexes on JSON objects or arrays to improve query performance