Now let’s look at the last group of JSON functions; those that are utilitarian in nature allowing you to get information about the JSON document and perform simple operations to help work with JSON documents.
116
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_DEPTH('[12,3,4,5,6]');
+---+
| JSON_DEPTH('[12,3,4,5,6]') | +---+
| 2 | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_DEPTH('[[], {}]');
+---+
| JSON_DEPTH('[[], {}]') | +---+
| 2 | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SET @base = '{"grapes":["red","white",
"green"],"berries":["strawberry","raspberry","boysenberry","blackberrry"],
"numbers":["1","2","3","4","5"]}';
Query OK, 0 rows affected (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_DEPTH(@base);
+---+
| JSON_DEPTH(@base) | +---+
| 3 | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_DEPTH(JSON_EXTRACT(@base, '$.grapes'));
+---+
| JSON_DEPTH(JSON_EXTRACT(@base, '$.grapes')) | +---+
| 2 | +---+
1 row in set (0.00 sec) Chapter 3 JSON DOCumeNtS
The JSON_KEYS() function is used to return a list of keys from the top-level value of a JSON object as a JSON array. The function also allows you to pass a path expression, which results in a list of the top-level keys from the selected path expression value.
An error occurs if the json_doc argument is not a valid JSON document or the path argument is not a valid path expression or contains a * or ** wildcard. The resulting array is empty if the selected object is empty.
There is one limitation. If the top-level value has nested JSON objects, the array returned does not include keys from those nested objects. Listing 3-18 shows several examples of using this function.
Listing 3-18. Using the JSON_KEYS Function
MySQL localhost:33060+ ssl SQL > SET @base = '{"grapes":["red","white",
"green"],"berries":["strawberry","raspberry","boysenberry","blackberrry"],
"numbers":["1","2","3","4","5"]}';
Query OK, 0 rows affected (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_KEYS(@base);
+---+
| JSON_KEYS(@base) | +---+
| ["grapes", "berries", "numbers"] | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_KEYS(@base,'$');
+---+
| JSON_KEYS(@base,'$') | +---+
| ["grapes", "berries", "numbers"] | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_KEYS('{"z":123,"x":
{"albedo":50}}');
118
+---+
| JSON_KEYS('{"z":123,"x":{"albedo":50}}') | +---+
| ["x", "z"] | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_KEYS('{"z":123,"x":
{"albedo":50}}', '$.x');
+---+
| JSON_KEYS('{"z":123,"x":{"albedo":50}}', '$.x') | +---+
| ["albedo"] | +---+
1 row in set (0.00 sec)
The JSON_LENGTH() function returns the length of the JSON document passed. It also allows you to pass in a path expression and if provided, will return the length of the value that matches the path expression. An error occurs if the json_doc argument is not a valid JSON document or the path argument is not a valid path expression or contains a * or **
wildcard. However, the value returned has several constraints as in the following:
• A scalar has length 1.
• An array has a length equal to the number of array elements.
• An object has a length equal to the number of object members.
However, there is one surprising limitation: the length returned does not count the length of nested arrays or objects. Thus, you must use this function carefully using the path expression for nested documents.
Listing 3-19 shows several examples of using the function.
Listing 3-19. Using the JSON_LENGTH Function
MySQL localhost:33060+ ssl SQL > SET @base = '{"grapes":["red","white",
"green"],"berries":["strawberry","raspberry","boysenberry","blackberrry"],
"numbers":["1","2","3","4","5"]}';
Query OK, 0 rows affected (0.00 sec) Chapter 3 JSON DOCumeNtS
MySQL localhost:33060+ ssl SQL > SELECT JSON_LENGTH(@base,'$');
+---+
| JSON_LENGTH(@base,'$') | +---+
| 3 | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_LENGTH(@base,'$.grapes');
+---+
| JSON_LENGTH(@base,'$.grapes') | +---+
| 3 | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_LENGTH(@base,'$.grapes[1]');
+---+
| JSON_LENGTH(@base,'$.grapes[1]') | +---+
| 1 | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_LENGTH(@base,'$.grapes[4]');
+---+
| JSON_LENGTH(@base,'$.grapes[4]') | +---+
| NULL | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_LENGTH(@base,'$.berries');
+---+
| JSON_LENGTH(@base,'$.berries') | +---+
| 4 | +---+
1 row in set (0.00 sec)
120
MySQL localhost:33060+ ssl SQL > SELECT JSON_LENGTH(@base,'$.numbers');
+---+
| JSON_LENGTH(@base,'$.numbers') | +---+
| 5 | +---+
1 row in set (0.00 sec)
Note the fourth command returns null because the path expression, although valid syntax, does not evaluate to a value or nested JSON array or object.
The JSON_QUOTE() function is a handy function to use that will help you add quotes where they are appropriate. That is, the function quotes a string as a JSON string by wrapping it with double quote characters and escaping interior quote and other characters and returns the result. Note that this function does not operate on a JSON document, rather, only a string.
You can use this function to produce a valid JSON string literal for inclusion within a JSON document. Listing 3-20 shows a few short examples of using the function to quote JSON strings.
Listing 3-20. Using the JSON_QUOTE Function
MySQL localhost:33060+ ssl SQL > SELECT JSON_QUOTE("test");
+---+
| JSON_QUOTE("test") | +---+
| "test" | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_QUOTE('[true]');
+---+
| JSON_QUOTE('[true]') | +---+
| "[true]" | +---+
1 row in set (0.00 sec) Chapter 3 JSON DOCumeNtS
MySQL localhost:33060+ ssl SQL > SELECT JSON_QUOTE('90125');
+---+
| JSON_QUOTE('90125') | +---+
| "90125" | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_QUOTE('["red","white","green"]');
+---+
| JSON_QUOTE('["red","white","green"]') | +---+
| "[\"red\",\"white\",\"green\"]" | +---+
1 row in set (0.00 sec)
Note that in the last example the function adds the escape character (\) because the string passed contains quotes. Why is this happening? Remember, this function takes a string, not a JSON array as the parameter.
The JSON_UNQUOTE() function is the opposite of the JSON_QUOTE() function. The JSON_UNQUOTE() function removes quotes JSON value and returns the result as a
utf8mb4 string. The function is designed to recognize and not alter markup sequences as in the following:
• \": A double quote (") character
• \b: A backspace character
• \f: A formfeed character
• \n: A newline (linefeed) character
• \r: A carriage return character
• \t: A tab character
• \\: A backslash (\) character
Listing 3-21 shows examples of using the function.
122
Listing 3-21. Using the JSON_UNQUOTE Function
MySQL localhost:33060+ ssl SQL > SELECT JSON_UNQUOTE("test 123");
+---+
| JSON_UNQUOTE("test 123") | +---+
| test 123 | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_UNQUOTE('"true"');
+---+
| JSON_UNQUOTE('"true"') | +---+
| true | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_UNQUOTE('\"true\"');
+---+
| JSON_UNQUOTE('\"true\"') | +---+
| true | +---+
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_UNQUOTE('9\t0\t125\\');
+---+
| JSON_UNQUOTE('9\t0\t125\\') | +---+
| 9 0 125\ | +---+
1 row in set (0.00 sec)
The JSON_PRETTY() function formats a JSON document for easier viewing. You can use this to produce an output to send to users or to make the JSON look a bit nicer in the shell. Listing 3-22 shows an example without the function and the same with the function. Note how much easier it is to read when using JSON_PRETTY().
Chapter 3 JSON DOCumeNtS
Listing 3-22. Using the JSON_PRETTY Function
MySQL localhost:33060+ ssl SQL > SET @base = '{"name": {"last":
"Throckmutton", "first": "Billy-bob"}, "address": {"zip": "90125", "city":
"Melborne", "state": "California", "street": "4 Main Street"}}';
Query OK, 0 rows affected (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT @base \G
*************************** 1. row ***************************
@base: {"name": {"last": "Throckmutton", "first": "Billy-bob"}, "address":
{"zip": "90125", "city": "Melborne", "state": "California", "street":
"4 Main Street"}}
1 row in set (0.00 sec)
MySQL localhost:33060+ ssl SQL > SELECT JSON_PRETTY(@base) \G
*************************** 1. row ***************************
JSON_PRETTY(@base): { "name": {
"last": "Throckmutton", "first": "Billy-bob"
},
"address": { "zip": "90125", "city": "Melborne", "state": "California", "street": "4 Main Street"
} }
1 row in set (0.00 sec)
There are also functions for checking size; JSON_STORAGE_FREE() and JSON_STORAGE_
SIZE(). The first is used after a partial update and the second is used to get the size of the binary representation of the JSON document. See the online MySQL reference manual for more details on these functions as they are new and not commonly used except for very special circumstances in which size is a concern.
124
Finally, there is a new function released in version 8.0.4 intriguingly named JSON_
TABLE(). This function takes a JSON document and returns a tabular data list. In basic terms, rather than returning output as JSON, this function returns rows as a result set.
Thus, you can use this function where you need more traditional rows to work within your applications.
The function has some peculiar syntax. It takes as parameters a JSON document (array), and an expression path and column definition. The last two are not separated by a comma (strangely). This arrangement makes the function a bit harder to use but once you see a working example it is easier to understand. So, let’s do that. Listing 3-23 demonstrates how to use the function.
Listing 3-23. Using the JSON_TABLE Function
MySQL localhost:33060+ SQL > set @phones = '[{"name":"Bill Smith","phone":
"8013321033"},{"name":"Folley Finn","phone":"9991112222"},{"name":"Carrie Tonnesth","phone":"6498881212"}]';
Query OK, 0 rows affected (0.00 sec)
MySQL localhost:33060+ SQL > SELECT * FROM JSON_TABLE(@phones, "$[*]"
COLUMNS(name char(20) PATH '$.name', phone char(16) PATH '$.phone')) as phone_list;
+---+---+
| name | phone | +---+---+
| Bill Smith | 8013321033 |
| Folley Finn | 9991112222 |
| Carrie Tonnesth | 6498881212 | +---+---+
3 rows in set (0.00 sec)
Note that we are using a JSON array of names and phone numbers to keep it simple. The function is used as if it were a table so we add it to the FROM clause on a SELECT statement. The parameters are the JSON document, then the path and column definition. The expression path used is simply retrieving the entire element from the array. You can use a variety of path expression here if you wanted to select only part of the document to operate on. Next is the column definition and this should look familiar Chapter 3 JSON DOCumeNtS
to you—it’s like column definitions for tables. The difference is we append a path expression on the end with the keyword PATH. This simply locates the value in the JSON document.
As you can imagine, you can form complex definitions drilling down to precisely the elements you want. The demand and use cases for this function will likely grow given that it is a recent addition, but if you need to turn a JSON document into a result set, this function can achieve those results albeit with some creativity and path expressions.
For more information about the JSON_TABLE() function, see the section entitled
“JSON Table Functions” in the online MySQL reference manual.