Não há nada de errado com sua consulta. É o seu ambiente.
Problema
MySqlGrammar
traduz o field->key
notação nos nomes dos campos (no lado do Laravel) em field->'$.key'
-style extrações (no lado do MySQL):/**
* Wrap the given JSON selector.
*
* @param string $value
* @return string
*/
protected function wrapJsonSelector($value)
{
$path = explode('->', $value);
$field = $this->wrapValue(array_shift($path));
$path = collect($path)->map(function ($part) {
return '"'.$part.'"';
})->implode('.');
// Here:
return sprintf('%s->\'$.%s\'', $field, $path);
}
Acabei de confirmar que o MariaDB não suporta o
->
operador de extração
como um alias para o JSON_EXTRACT()
função. No entanto, a mesma consulta funciona em um servidor MySQL 5.7 vanilla. Assumindo este
teste
tabela:╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
Uma consulta que usa o
->
operador de extração:SELECT payload->"$.b" FROM test;
falha no MariaDB 10.2.8 enquanto produz um
2
correto contra um servidor MySQL 5.7.19. Soluções
A solução certa depende do que você está usando na produção.
Substituir MariaDB
Se você estiver usando MySQL, substitua MariaDB por MySQL em seu ambiente de desenvolvimento. Em uma máquina macOS gerenciada pelo homebrew, seria tão fácil quanto:
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
seus dados permanecerão intactos.
Reescreva suas consultas
No entanto, se você estiver usando o MariaDB em produção, precisará reescrever suas consultas para usar
JSON_EXTRACT()
funcionar como Elias já mencionado
. Como você pode ver, você precisa ser muito mais detalhado com a API do Laravel. A consulta acima seria:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;