• Tidak ada hasil yang ditemukan

+---+

| JSON_SET(@base, '$[0]', "orange", '$[2].grape[1]', "green", '$[9]', "123") | +---+

| ["orange", "pear", {"grape": ["red", "green"]}, "strawberry", "123"] | +---+

1 row in set (0.00 sec)

IGNORE OR NOT IGNORE, WHICH DOES WHAT?

One issue with the JSON functions is that some will operate on values that exist, others ignore values that exist, some add values that do not already exist, and so forth. It can become confusing if you aren’t familiar with all the functions. the following summarizes the differences for those functions that can be the most confusing.

• JSON_INSERT(): adds new values but does not replace existing values

• JSON_REMOVE(): removes elements that exist in the document and ignores those that do not exist

• JSON_REPLACE(): replaces existing values and ignores new values

• JSON_SET(): replaces values for paths that exist and adds values for paths that do not exist

If you want to use these functions, be sure to check them with sample data until you understand the conditions.

Now let’s look at the JSON functions you can use to find elements in the document.

106

There are four JSON functions that allow you to search JSON documents. As with the previous functions, these operate on a JSON document with one or more parameters. I call them searching functions not because they allow you to search a database or table for JSON data, but rather they allow you to find things in JSON documents. The functions include those for checking to see if a value or element exists in the document, whether a path expression is valid (something can be found using it), and retrieving information from the document.

The JSON_CONTAINS() function has two options: you can use it to return whether a value exists anywhere in the document or if a value exists using a path expression (the path expression is an optional parameter). The function returns a 0 or 1 where a 0 means the value was not found. An error occurs if either document argument is not a valid JSON document, the path argument is not a valid path expression, or contains a * or ** wildcard.

There is another catch. The value you pass in must be a valid JSON string or document.

Listing 3-13 shows several examples of using the function to search a JSON document.

Listing 3-13. Using the JSON_CONTAINS Function

MySQL localhost:33060+ ssl SQL > SET @base = '{"grapes":["red","white",

"green"],"berries":["strawberry","raspberry","boysenberry","blackberrry"]}';

Query OK, 0 rows affected (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS(@base,'["red",

"white","green"]');

+---+

| JSON_CONTAINS(@base,'["red","white","green"]') | +---+

| 0 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS(@base,'{"grapes":

["red","white","green"]}');

+---+

| JSON_CONTAINS(@base,'{"grapes":["red","white","green"]}') | +---+

| 1 | +---+

1 row in set (0.00 sec) Chapter 3 JSON DOCumeNtS

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS(@base,'["red",

"white","green"]','$.grapes');

+---+

| JSON_CONTAINS(@base,'["red","white","green"]','$.grapes') | +---+

| 1 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS(@base,'

"blackberry"','$.berries');

+---+

| JSON_CONTAINS(@base,'"blackberry"','$.berries') | +---+

| 0 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS(@base, 'blackberry','$.berries');

ERROR: 3141: Invalid JSON text in argument 2 to function json_contains:

"Invalid value." at position 0.

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS(@base,'"red"', '$.grapes');

+---+

| JSON_CONTAINS(@base,'"red"','$.grapes') | +---+

| 1 | +---+

1 row in set (0.00 sec)

As you can see, this is a very useful function but it requires a bit of care to use

properly. That is, you must make sure the value is a valid string. In all examples save one, I am searching the JSON document for either a JSON document (that makes searching for nested data easier), or a single value using a path expression. Remember, the function searches for values, not keys.

Note the second to last example: this returns an error because the value is not a valid JSON string. You must use double quotes around it to correct it as shown in the following example.

108

The JSON_CONTAINS_PATH() function uses a parameter strategy that is a little different. The function searches a JSON document to see if a path expression exists but it also allows you to find the first occurrence or all occurrences. It also can take multiple paths and evaluate them either as an “or” or “and” condition depending on what value you pass as the second parameter as in the following:

• If you pass one, the function will return 1 if at least one path expression is found (OR).

• If you pass all, the function will return 1 only if all path expressions are found (AND).

The function returns 0 or 1 to indicate whether a JSON document contains data at a given path or paths. Note that it can return null if any of the path expressions or the document is null. An error occurs if the JSON document, or any path expression is not valid, or the second parameter is not one or all. Listing 3-14 shows several examples of using the function.

Listing 3-14. Using the JSON_CONTAINS_PATH 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_CONTAINS_PATH(@base,'one','$');

+---+

| JSON_CONTAINS_PATH(@base,'one','$') | +---+

| 1 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base,'all','$');

+---+

| JSON_CONTAINS_PATH(@base,'all','$') | +---+

| 1 | +---+

Chapter 3 JSON DOCumeNtS

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'all','$.grapes','$.berries');

+---+

| JSON_CONTAINS_PATH(@base,'all','$.grapes','$.berries') | +---+

| 1 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'all','$.grapes','$.berries','$.numbers');

+---+

| JSON_CONTAINS_PATH(@base,'all','$.grapes','$.berries','$.numbers') | +---+

| 1 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'all','$.grapes','$.berries','$.num');

+---+

| JSON_CONTAINS_PATH(@base,'all','$.grapes','$.berries','$.num') | +---+

| 0 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'one','$.grapes','$.berries','$.num');

+---+

| JSON_CONTAINS_PATH(@base,'one','$.grapes','$.berries','$.num') | +---+

| 1 | +---+

1 row in set (0.00 sec)

110

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'one','$.grapes');

+---+

| JSON_CONTAINS_PATH(@base,'one','$.grapes') | +---+

| 1 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'all','$.grape');

+---+

| JSON_CONTAINS_PATH(@base,'all','$.grape') | +---+

| 0 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'one','$.berries');

+---+

| JSON_CONTAINS_PATH(@base,'one','$.berries') | +---+

| 1 | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_CONTAINS_PATH(@base, 'all','$.berries');

+---+

| JSON_CONTAINS_PATH(@base,'all','$.berries') | +---+

| 1 | +---+

1 row in set (0.00 sec) Chapter 3 JSON DOCumeNtS

Take some time to look through these examples so you can see how they work. Note that in the first two commands I used a path expression of a single dollar sign. This is simply the path expression to the entire document so naturally, it exists. Note also the differences in the use of one or all for the last two examples.

The JSON_EXTRACT() function is one of the most used functions. It allows you to extract a value, JSON array, JSON object, and so forth from a JSON document using one or more path expressions. We have already seen a couple of examples. Recall the function returns the portion of the JSON document that matches the path expression.

Listing 3-15 shows a few more examples using complex path expressions.

Listing 3-15. Using the JSON_EXTRACT 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_EXTRACT(@base,'$');

+---+

| JSON_EXTRACT(@base,'$') +---+

| {"grapes": ["red", "white", "green"], "berries": ["strawberry",

"raspberry", "boysenberry", "blackberry"], "numbers": ["1", "2", "3", "4",

"5"]} |

+---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_EXTRACT(@base,'$.grapes');

+---+

| JSON_EXTRACT(@base,'$.grapes') | +---+

| ["red", "white", "green"] | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_EXTRACT(@base,'$.grapes[*]');

112

+---+

| JSON_EXTRACT(@base,'$.grapes[*]') | +---+

| ["red", "white", "green"] | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_EXTRACT(@base,'$.grapes[1]');

+---+

| JSON_EXTRACT(@base,'$.grapes[1]') | +---+

| "white" | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_EXTRACT(@base,'$.grapes[4]');

+---+

| JSON_EXTRACT(@base,'$.grapes[4]') | +---+

| NULL | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_EXTRACT(@base,'$.berries');

+---+

| JSON_EXTRACT(@base,'$.berries') | +---+

| ["strawberry", "raspberry", "boysenberry", "blackberry"] | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_EXTRACT(@base,'$.berries[2]');

+---+

| JSON_EXTRACT(@base,'$.berries[2]') | +---+

| "boysenberry" | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_EXTRACT(@base, '$.berries[2]','$.berries[3]');

Chapter 3 JSON DOCumeNtS

+---+

| JSON_EXTRACT(@base,'$.berries[2]','$.berries[3]') | +---+

| ["boysenberry", "blackberry"] | +---+

1 row in set (0.00 sec)

Note what happens when we use the single dollar sign. The function returns the entire document. Also, note what happens when we use a path expression, although its syntax is valid it does not evaluate to an element in the document (see the fifth command).

Note the last example where we pass in two path expressions. Then notice how it returns a JSON array whereas the example before it with only one path expression returns a JSON string value. This is one of the trickier aspects of the function. So long as you remember it returns a valid JSON string, array, or object, you will be able to use the function without issue.

The JSON_SEARCH() function is interesting because it is the opposite of the

JSON_EXTRACT() function. More specific, it takes one or more values and returns path expressions to the values if they are found in the document. This makes it easier to validate your path expressions or to build path expressions on the fly.

As with the JSON_CONTAINS_PATH() function, the JSON_SEARCH() function also allows you to find the first occurrence or all occurrences returning the path expressions depending on what value you pass as the second parameter as in the following:

• If you pass one, the function will return the first match.

• If you pass all, the function will return all matches.

But there is a trick here too. The function takes a third parameter that forms a special search string that works as the LIKE operator in SQL statements. That is, search string argument can use the % and _ characters the same way as the LIKE operator. Note that to use a % or _ as a literal, you must precede it with the \ (escape) character.

The function returns 0 or 1 to indicate whether a JSON document contains the values. Note that it can return null if any of the path expressions or the document is null.

An error occurs if the JSON document, or any path expression is not valid, or the second parameter is not one or all. Listing 3-16 shows several examples of using the function.

114

Listing 3-16. Using the JSON_SEARCH 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_SEARCH(@base,'all','red');

+---+

| JSON_SEARCH(@base,'all','red') | +---+

| "$.grapes[0]" | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_SEARCH(@base,'all','gr____');

+---+

| JSON_SEARCH(@base,'all','gr____') | +---+

| NULL | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_SEARCH(@base,'one','%berry');

+---+

| JSON_SEARCH(@base,'one','%berry') | +---+

| "$.berries[0]" | +---+

1 row in set (0.00 sec)

MySQL localhost:33060+ ssl SQL > SELECT JSON_SEARCH(@base,'all','%berry');

+---+

| JSON_SEARCH(@base,'all','%berry') | +---+

| ["$.berries[0]", "$.berries[1]", "$.berries[2]"] | +---+

1 row in set (0.00 sec) Chapter 3 JSON DOCumeNtS

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.