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 buscarone_or_all
es la palabra claveone
oall
. Si usasone
, 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. Siall
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 | +--------+