No MySQL, o
JSON_SEARCH()
A função retorna o caminho para uma determinada string em um documento JSON. Você fornece o documento JSON como um argumento para a função. Você também fornece o argumento que determina a string real a ser pesquisada (incluindo quaisquer caracteres de escape), bem como uma palavra-chave para indicar se deve retornar o caminho de todas as instâncias ou apenas uma.
Sintaxe
A sintaxe fica assim:
JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])
A explicação de cada argumento segue.
json_doc
é o documento JSON a ser pesquisadoone_or_all
é a palavra-chaveone
ouall
. Se você usarone
, a pesquisa será interrompida assim que a primeira ocorrência for encontrada. Ou seja, a função retorna apenas o caminho da primeira instância da string de pesquisa. Seall
for especificado, os caminhos de todas as ocorrências serão retornados de modo que nenhum caminho duplicado seja incluído. Se houver vários caminhos, eles serão encapsulados automaticamente como uma matriz.search_str
é a string real para retornar o caminho.escape_char
é um caractere opcional para ser usado como caractere de escape. Deve ser uma constante vazia ou um caractere. Se você não especificar este argumento (ou se for NULL), o caractere de escape será a barra invertida (\
).path
é um argumento opcional para determinar onde o caminho de "nível superior" começa no documento JSON.
Dentro do
search_str
argumento, o %
e _
os caracteres funcionam exatamente como quando usados com o LIKE
operador:%
corresponde a qualquer número de caracteres (incluindo zero caracteres) e _
corresponde exatamente a um caractere. Para especificar um literal
%
ou _
caractere na string de pesquisa, preceda-o pelo caractere de escape. Exemplo 1 – Uso básico
Aqui está um exemplo para demonstrar.
SELECT JSON_SEARCH('{"Nome":"Bart", "Idade":10}', 'um', 'Bart') Resultado;
Resultado:
+----------+| Resultado |+----------+| "$.Nome" |+----------+
Exemplo 2 – Matrizes
Aqui está um exemplo de como encontrar uma string dentro de um array.
SET @doc ='{"Name":"Bart", "Hobbies":["Skateboarding", "Mischief"]}';SELECT JSON_SEARCH(@doc, 'one', 'Mischief') Resultado;
Resultado:
+----------------+| Resultado |+----------------+| "$.Hobbies[1]" |+----------------+
Arrays usam numeração baseada em zero, então este resultado indica o segundo elemento.
Exemplo 3 - String inexistente
Se você especificar uma string que não existe, um valor NULL será retornado.
SET @doc ='{"Name":"Bart", "Hobbies":["Skateboarding", "Mischief"]}';SELECT JSON_SEARCH(@doc, 'one', 'Homer') Result;
Resultado:
+--------+| Resultado |+--------+| NULO |+--------+
Você também receberá um valor NULL se algum dosjson_doc
,search_str
, oupath
argumentos sãoNULL
ou se não existir nenhum caminho no objeto JSON.
Exemplo 4 – Ocorrências múltiplas de uma string
Se o documento JSON contiver várias ocorrências da mesma string, o resultado dependerá se você especificarone
ouall
como segundo argumento.
Se você usarone
, apenas a primeira ocorrência é retornada (supondo que haja pelo menos uma ocorrência):
SET @doc ='{"Nome":"Bart", "Amigos":["Bart", "Milhouse"]}';SELECT JSON_SEARCH(@doc, 'um', 'Bart') Resultado;
Resultado:
+----------+| Resultado |+----------+| "$.Nome" |+----------+
Se você usarall
, os caminhos de todas as ocorrências são retornados. Se houver mais de um caminho, eles serão encapsulados automaticamente como uma matriz.
SET @doc ='{"Nome":"Bart", "Amigos":["Bart", "Milhouse"]}';SELECT JSON_SEARCH(@doc, 'all', 'Bart') Resultado;
Resultado:
+----------------------------+| Resultado |+----------------------------+| ["$.Nome", "$.Amigos[0]"] |+----------------------------+
Você também pode especificar um caminho que retorne apenas os resultados de um caminho especificado. Mais sobre isso abaixo (em Exemplo 8 – Especificar um caminho ).
Exemplo 5 – Curingas
Você pode usar caracteres curinga conforme especificado na sintaxe acima. Por exemplo, você pode usar o%
para corresponder a qualquer número de caracteres.
SET @doc ='{"Name":"Bart", "Hobbies":["Skateboarding", "Mischief"]}';SELECT JSON_SEARCH(@doc, 'one', 'Skate%') Result;
Resultado:
+----------------+| Resultado |+----------------+| "$.Hobbies[0]" |+----------------+
E você pode usar_
para corresponder apenas a um caractere.
SET @doc ='{"Name":"Bart", "Hobbies":["Skateboarding", "Mischief"]}';SELECT JSON_SEARCH(@doc, 'one', 'Bar_') Resultado;
Resultado:
+----------+| Resultado |+----------+| "$.Nome" |+----------+
Se fôssemos usar o_
no exemplo anterior, obteríamos um resultado NULL.
SET @doc ='{"Name":"Bart", "Hobbies":["Skateboarding", "Mischief"]}';SELECT JSON_SEARCH(@doc, 'one', 'Skate_') Resultado;
Resultado:
+--------+| Resultado |+--------+| NULO |+--------+Exemplo 6 – Caractere de escape padrão
Se você precisar procurar uma string que realmente contenha qualquer um dos caracteres curinga acima, precisará escapar do caractere. Isso diz ao MySQL para usá-lo como um literal de string (em vez de interpretá-lo como um caractere curinga).
SET @doc ='{"userid":"bart_simpson", "pwd":"pass%word"}';SELECT JSON_SEARCH(@doc, 'one', 'pass\%word') Resultado;
Resultado:
+---------+| Resultado |+---------+| "$.pwd" |+---------+
À primeira vista, você pode estar pensando que a barra invertida era desnecessária, pois, afinal, obteríamos o mesmo resultado se fizermos isso:
SET @doc ='{"userid":"bart_simpson", "pwd":"pass%word"}';SELECT JSON_SEARCH(@doc, 'one', 'pass%word') Resultado;
Resultado:
+---------+| Resultado |+---------+| "$.pwd" |+---------+
Mas o problema com essa abordagem é que também obtemos o mesmo resultado se fizermos isso:
SET @doc ='{"userid":"bart_simpson", "pwd":"pass%BLAH-BLAH-BLAH-word"}';SELECT JSON_SEARCH(@doc, 'one', 'pass%word' ) 'Resultado';
Resultado:
+---------+| Resultado |+---------+| "$.pwd" |+---------+
Portanto, a barra invertida informa ao MySQL que estamos procurando apenas uma única instância de%
como um literal de string e não para qualquer número de outros caracteres.
O mesmo conceito vale para o caractere de sublinhado.
Se fizermos isso:
SET @doc ='{"userid":"bart_simpson", "pwd":"pass%word"}';SELECT JSON_SEARCH(@doc, 'one', 'bart\_simpson') 'Escaped', JSON_SEARCH (@doc, 'um', 'bart_simpson') 'Não escapou';
Obtemos isso:
+------------+-------------+| Escapou | Não escapou |+------------+-------------+| "$.userid" | "$.userid" |+------------+-------------+
Ambas as abordagens retornam o mesmo resultado.
Mas se fizermos isso (substitua o _ por J no userid):
SET @doc ='{"userid":"bartJsimpson", "pwd":"pass%word"}';SELECT JSON_SEARCH(@doc, 'one', 'bart\_simpson') 'Escaped', JSON_SEARCH (@doc, 'um', 'bart_simpson') 'Não escapou';
Obtemos isso:
+---------+-------------+| Escapou | Sem Escape |+---------+-------------+| NULO | "$.userid" |+---------+-------------+Exemplo 7 – Caractere de escape personalizado
Você pode especificar seu próprio caractere de escape, se necessário. Você faz isso incluindo-o como um quarto argumento opcional.
Aqui está o exemplo anterior reescrito para usar um caractere de escape diferente (o ID do usuário inclui um_
personagem).
SET @doc ='{"userid":"bart_simpson", "pwd":"pass%word"}';SELECT JSON_SEARCH(@doc, 'one', 'bart$_simpson', '$') ' Escapou', JSON_SEARCH(@doc, 'one', 'bart_simpson') 'Não escapou';
Resultado:
+------------+-------------+| Escapou | Não escapou |+------------+-------------+| "$.userid" | "$.userid" |+------------+-------------+
E se substituirmos o_
comJ
no ID do usuário:
SET @doc ='{"userid":"bartJsimpson", "pwd":"pass%word"}';SELECT JSON_SEARCH(@doc, 'one', 'bart$_simpson', '$') ' Escapou', JSON_SEARCH(@doc, 'one', 'bart_simpson') 'Não escapou';
Resultado:
+---------+-------------+| Escapou | Sem Escape |+---------+-------------+| NULO | "$.userid" |+---------+-------------+Exemplo 8 – Especificar um caminho
Você também pode especificar um caminho a partir do qual iniciar a pesquisa. Aqui está um exemplo.
SET @data ='{ "Pessoa":{ "Nome":"Bart", "Idade":10, "Amigos":["Bart", "Milhouse"] } }';SELECT JSON_SEARCH(@data , 'todos', 'Bart', NULL, '$.Pessoa.Amigos') AS 'Resultado';
Resultado:
+-----------------------+| Resultado |+-----------------------+| "$.Pessoa.Amigos[0]" |+----------------------------------+
Se não tivéssemos especificado um caminho, obteríamos o seguinte resultado.
SET @data ='{ "Pessoa":{ "Nome":"Bart", "Idade":10, "Amigos":["Bart", "Milhouse"] } }';SELECT JSON_SEARCH(@data , 'todos', 'Bart') AS 'Resultado';
Resultado:
+------------------------------------------+| Resultado |+------------------------------------------+| ["$.Pessoa.Nome", "$.Pessoa.Amigos[0]"] |+---------------------------- --------------+
Além disso, se tivéssemos especificadoone
como segundo argumento (além de omitir o argumento de caminho), teríamos o seguinte.
SET @data ='{ "Pessoa":{ "Nome":"Bart", "Idade":10, "Amigos":["Bart", "Milhouse"] } }';SELECT JSON_SEARCH(@data , 'um', 'Bart') AS 'Resultado';
Resultado:
+-----------------+| Resultado |+-----------------+| "$.Pessoa.Nome" |+-----------------+Exemplo 9 - Documento vazio
Se o documento não contiver caminhos, você obterá um valor NULL.
SELECT JSON_SEARCH('{}', 'all', 'Bart') 'Result';
Resultado:
+--------+| Resultado |+--------+| NULO |+--------+