Er is niets mis met je vraag. Het is jouw omgeving.
Probleem
Laravel's MySqlGrammar
vertaalt de field->key
notatie in veldnamen (aan Laravel-kant) in field->'$.key'
-stijl extracties (aan MySQL-kant):
/**
* 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);
}
Ik heb zojuist bevestigd dat MariaDB de ->
extractie-operator
als een alias voor de JSON_EXTRACT()
functie. Dezelfde query werkt echter tegen een vanille MySQL 5.7-server.
Uitgaande van deze test
tabel:
╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
Een query die de ->
. gebruikt extractie-operator:
SELECT payload->"$.b" FROM test;
mislukt tegen MariaDB 10.2.8 terwijl het een correcte 2
. oplevert tegen een MySQL 5.7.19-server.
Oplossingen
De juiste oplossing hangt af van wat u bij de productie gebruikt.
Vervang MariaDB
Als u MySQL gebruikt, vervangt u MariaDB door MySQL in uw ontwikkelomgeving. Op een macOS-machine beheerd door homebrew, zou het zo eenvoudig zijn als:
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
uw gegevens blijven intact.
Herschrijf uw zoekopdrachten
Als u MariaDB echter in productie gebruikt, moet u uw query's herschrijven om JSON_EXTRACT()
te gebruiken functioneren als Elias al genoemd
. Zoals je kunt zien, moet je veel uitgebreider zijn met de Laravel API.
De bovenstaande vraag zou zijn:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;