sql >> Base de Datos >  >> RDS >> Mysql

JSON_SEARCH():encuentre la ruta a una cadena en un documento JSON en MySQL

En MySQL, JSON_SEARCH() La función devuelve la ruta a una cadena dada en un documento JSON.

Proporciona el documento JSON como argumento para la función. También proporciona el argumento que determina la cadena real para buscar (incluidos los caracteres de escape), así como una palabra clave para indicar si devolver la ruta de todas las instancias o solo una.

Sintaxis

La sintaxis es así:

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

A continuación se explica cada argumento.

  • json_doc es el documento JSON para buscar
  • one_or_all es la palabra clave one o all . Si usas one , la búsqueda se detiene una vez que se encuentra la primera aparición. Es decir, la función solo devuelve la ruta de la primera instancia de la cadena de búsqueda. Si all se especifica, se devuelven las rutas de todas las apariciones de modo que no se incluyan rutas duplicadas. Si hay varias rutas, se ajustan automáticamente como una matriz.
  • search_str es la cadena real para devolver la ruta de.
  • escape_char es un carácter opcional para usar como carácter de escape. Debe ser una constante que esté vacía o un carácter. Si no especifica este argumento (o si es NULL), el carácter de escape es la barra invertida (\ ).
  • path es un argumento opcional para determinar dónde comienza la ruta de "nivel superior" dentro del documento JSON.

Dentro de search_str argumento, el % y _ los caracteres funcionan igual que cuando se usan con LIKE operador:% coincide con cualquier número de caracteres (incluidos cero caracteres) y _ coincide exactamente con un carácter.

Para especificar un literal % o _ carácter en la cadena de búsqueda, precedido por el carácter de escape.

Ejemplo 1:uso básico

Aquí hay un ejemplo para demostrarlo.

SELECT 
  JSON_SEARCH('{"Name": "Bart", "Age": 10}', 'one', 'Bart') Result;

Resultado:

+----------+
| Result   |
+----------+
| "$.Name" |
+----------+

Ejemplo 2:matrices

Este es un ejemplo de cómo encontrar una cadena dentro de una matriz.

SET @doc = '{"Name": "Bart", "Hobbies": ["Skateboarding", "Mischief"]}';
SELECT JSON_SEARCH(@doc, 'one', 'Mischief') Result;

Resultado:

+----------------+
| Result         |
+----------------+
| "$.Hobbies[1]" |
+----------------+

Las matrices usan numeración basada en cero, por lo que este resultado indica el segundo elemento.

Ejemplo 3:cadena inexistente

Si especifica una cadena que no existe, se devuelve un valor NULL.

SET @doc = '{"Name": "Bart", "Hobbies": ["Skateboarding", "Mischief"]}';
SELECT JSON_SEARCH(@doc, 'one', 'Homer') Result;

Resultado:

+--------+
| Result |
+--------+
| NULL   |
+--------+

También obtendrá un valor NULL si alguno de los json_doc , search_str , o path los argumentos son NULL o si no existe una ruta dentro del objeto JSON.

Ejemplo 4:Múltiples ocurrencias de una cadena

Si el documento JSON contiene varias apariciones de la misma cadena, el resultado dependerá de si especifica one o all como segundo argumento.

Si usas one , solo se devuelve la primera aparición (suponiendo que haya al menos una aparición):

SET @doc = '{"Name": "Bart", "Friends": ["Bart", "Milhouse"]}';
SELECT JSON_SEARCH(@doc, 'one', 'Bart') Result;

Resultado:

+----------+
| Result   |
+----------+
| "$.Name" |
+----------+

Si usa all , se devuelven las rutas de todas las apariciones. Si hay más de una ruta, se ajustan automáticamente como una matriz.

SET @doc = '{"Name": "Bart", "Friends": ["Bart", "Milhouse"]}';
SELECT JSON_SEARCH(@doc, 'all', 'Bart') Result;

Resultado:

+----------------------------+
| Result                     |
+----------------------------+
| ["$.Name", "$.Friends[0]"] |
+----------------------------+

También puede especificar una ruta que devuelva solo los resultados de una ruta específica. Más sobre eso a continuación (en Ejemplo 8:especifique una ruta ).

Ejemplo 5:comodines

Puede usar caracteres comodín como se especifica en la sintaxis anterior. Por ejemplo, puede usar el % para que coincida con cualquier número de caracteres.

SET @doc = '{"Name": "Bart", "Hobbies": ["Skateboarding", "Mischief"]}';
SELECT JSON_SEARCH(@doc, 'one', 'Skate%') Result;

Resultado:

+----------------+
| Result         |
+----------------+
| "$.Hobbies[0]" |
+----------------+

Y puedes usar _ para que coincida con un solo carácter.

SET @doc = '{"Name": "Bart", "Hobbies": ["Skateboarding", "Mischief"]}';
SELECT JSON_SEARCH(@doc, 'one', 'Bar_') Result;

Resultado:

+----------+
| Result   |
+----------+
| "$.Name" |
+----------+

Si tuviéramos que usar el _ en el ejemplo anterior, obtendríamos un resultado NULL.

SET @doc = '{"Name": "Bart", "Hobbies": ["Skateboarding", "Mischief"]}';
SELECT JSON_SEARCH(@doc, 'one', 'Skate_') Result;

Resultado:

+--------+
| Result |
+--------+
| NULL   |
+--------+

Ejemplo 6:carácter de escape predeterminado

Si necesita buscar una cadena que realmente contenga cualquiera de los caracteres comodín anteriores, deberá escapar del carácter. Eso le dice a MySQL que lo use como un literal de cadena (en lugar de interpretarlo como un carácter comodín).

SET @doc = '{"userid": "bart_simpson", "pwd": "pass%word"}';
SELECT JSON_SEARCH(@doc, 'one', 'pass\%word') Result;

Resultado:

+---------+
| Result  |
+---------+
| "$.pwd" |
+---------+

A primera vista, puede estar pensando que la barra invertida era innecesaria, porque después de todo, obtendríamos el mismo resultado si hacemos esto:

SET @doc = '{"userid": "bart_simpson", "pwd": "pass%word"}';
SELECT JSON_SEARCH(@doc, 'one', 'pass%word') Result;

Resultado:

+---------+
| Result  |
+---------+
| "$.pwd" |
+---------+

Pero el problema con este enfoque es que también obtenemos el mismo resultado si hacemos esto:

SET @doc = '{"userid": "bart_simpson", "pwd": "pass%BLAH-BLAH-BLAH-word"}';
SELECT JSON_SEARCH(@doc, 'one', 'pass%word') 'Result';

Resultado:

+---------+
| Result  |
+---------+
| "$.pwd" |
+---------+

Entonces, la barra invertida informa a MySQL que solo estamos buscando una única instancia de % como un literal de cadena, y no para cualquier número de otros caracteres.

El mismo concepto es válido para el carácter de subrayado.

Si hacemos esto:

SET @doc = '{"userid": "bart_simpson", "pwd": "pass%word"}';
SELECT 
  JSON_SEARCH(@doc, 'one', 'bart\_simpson') 'Escaped',
  JSON_SEARCH(@doc, 'one', 'bart_simpson') 'Not Escaped';

Obtenemos esto:

+------------+-------------+
| Escaped    | Not Escaped |
+------------+-------------+
| "$.userid" | "$.userid"  |
+------------+-------------+

Ambos enfoques devuelven el mismo resultado.

Pero si hacemos esto (reemplazar el _ con J en el ID de usuario):

SET @doc = '{"userid": "bartJsimpson", "pwd": "pass%word"}';
SELECT 
  JSON_SEARCH(@doc, 'one', 'bart\_simpson') 'Escaped',
  JSON_SEARCH(@doc, 'one', 'bart_simpson') 'Not Escaped';

Obtenemos esto:

+---------+-------------+
| Escaped | Not Escaped |
+---------+-------------+
| NULL    | "$.userid"  |
+---------+-------------+

Ejemplo 7:carácter de escape personalizado

Puede especificar su propio carácter de escape si es necesario. Para ello, inclúyalo como un cuarto argumento opcional.

Aquí está el ejemplo anterior reescrito para usar un carácter de escape diferente (el ID de usuario incluye un _ personaje).

SET @doc = '{"userid": "bart_simpson", "pwd": "pass%word"}';
SELECT 
  JSON_SEARCH(@doc, 'one', 'bart$_simpson', '$') 'Escaped',
  JSON_SEARCH(@doc, 'one', 'bart_simpson') 'Not Escaped';

Resultado:

+------------+-------------+
| Escaped    | Not Escaped |
+------------+-------------+
| "$.userid" | "$.userid"  |
+------------+-------------+

Y si reemplazamos el _ con J en el ID de usuario:

SET @doc = '{"userid": "bartJsimpson", "pwd": "pass%word"}';
SELECT 
  JSON_SEARCH(@doc, 'one', 'bart$_simpson', '$') 'Escaped',
  JSON_SEARCH(@doc, 'one', 'bart_simpson') 'Not Escaped';

Resultado:

+---------+-------------+
| Escaped | Not Escaped |
+---------+-------------+
| NULL    | "$.userid"  |
+---------+-------------+

Ejemplo 8:especificar una ruta

También puede especificar una ruta desde la que empezar a buscar. He aquí un ejemplo.

SET @data = '{  
    "Person": {    
       "Name": "Bart", 
       "Age": 10,
       "Friends": ["Bart", "Milhouse"]  
    }
 }';
SELECT JSON_SEARCH(@data, 'all', 'Bart', NULL, '$.Person.Friends') AS 'Result';

Resultado:

+-----------------------+
| Result                |
+-----------------------+
| "$.Person.Friends[0]" |
+-----------------------+

Si no hubiéramos especificado una ruta, obtendríamos el siguiente resultado.

SET @data = '{  
    "Person": {    
       "Name": "Bart", 
       "Age": 10,
       "Friends": ["Bart", "Milhouse"]  
    }
 }';
SELECT JSON_SEARCH(@data, 'all', 'Bart') AS 'Result';

Resultado:

+------------------------------------------+
| Result                                   |
+------------------------------------------+
| ["$.Person.Name", "$.Person.Friends[0]"] |
+------------------------------------------+

Además, si hubiéramos especificado one como segundo argumento (además de omitir el argumento de la ruta), terminaríamos con lo siguiente.

SET @data = '{  
    "Person": {    
       "Name": "Bart", 
       "Age": 10,
       "Friends": ["Bart", "Milhouse"]  
    }
 }';
SELECT JSON_SEARCH(@data, 'one', 'Bart') AS 'Result';

Resultado:

+-----------------+
| Result          |
+-----------------+
| "$.Person.Name" |
+-----------------+

Ejemplo 9:documento vacío

Si el documento no contiene rutas, obtendrá un valor NULL.

SELECT 
  JSON_SEARCH('{}', 'all', 'Bart') 'Result';

Resultado:

+--------+
| Result |
+--------+
| NULL   |
+--------+