Tidak ada yang salah dengan kueri Anda. Ini adalah lingkungan Anda.
Masalah
MySqlGrammar
menerjemahkan field->key
notasi pada nama field (pada sisi Laravel) menjadi field->'$.key'
-ekstraksi gaya (di sisi 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);
}
Saya baru saja mengonfirmasi bahwa MariaDB tidak mendukung ->
operator ekstraksi
sebagai alias untuk JSON_EXTRACT()
fungsi. Namun, kueri yang sama berfungsi pada server vanilla MySQL 5.7.
Dengan asumsi test
. ini tabel:
╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
Kueri yang menggunakan ->
operator ekstraksi:
SELECT payload->"$.b" FROM test;
gagal terhadap MariaDB 10.2.8 saat menghasilkan 2
yang benar terhadap server MySQL 5.7.19.
Solusi
Solusi yang tepat tergantung pada apa yang Anda gunakan pada produksi.
Ganti MariaDB
Jika Anda menggunakan MySQL, ganti MariaDB dengan MySQL di env pengembangan Anda. Pada mesin macOS yang dikelola oleh homebrew, akan semudah:
brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
data Anda akan tetap utuh.
Tulis ulang kueri Anda
Namun, jika Anda menggunakan MariaDB dalam produksi, Anda perlu menulis ulang kueri Anda untuk menggunakan JSON_EXTRACT()
berfungsi sebagai Elias sudah disebutkan
. Seperti yang Anda lihat, Anda harus lebih bertele-tele dengan Laravel API.
Pertanyaan di atas adalah:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;