因此,我想通过将某个ID与notifications
列进行比较来查询Laravel中的data
表。这就是data
列的样子:
{
"Message": "some message",
"id": 3
}
现在,我需要选择ID等于3的所有通知。以下是我尝试执行此操作的方法:
DB::table('notifications')->where('data->id', '3')->get();
但是这会引发以下错误:
SQLSTATE [42000]:语法错误或访问冲突:1064您有 SQL语法错误;查看与您的手册相对应的手册 MariaDB服务器版本,用于在'>' $。" id"'附近使用正确的语法。 = ?'在第1行(SQL:select * from
notifications
wheredata
- >' $" ID"' = 3)
我在这里失去理智,任何人都可以帮助我吗?
答案 0 :(得分:7)
您的查询没有任何问题。这是你的环境。
Laravel的MySqlGrammar
将字段名称中的field->key
表示法(在Laravel方面)转换为field->'$.key'
- 样式的提取(在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);
}
我刚刚确认MariaDB不支持->
extraction operator作为JSON_EXTRACT()
函数的别名。但是,相同的查询适用于vanilla MySQL 5.7服务器。
假设这个test
表:
╔════╤══════════════════╗
║ id │ payload ║
╟────┼──────────────────╢
║ 1 │ {"a": 1, "b": 2} ║
╚════╧══════════════════╝
使用->
提取运算符的查询:
SELECT payload->"$.b" FROM test;
对MariaDB 10.2.8失败,而它对MySQL 5.7.19服务器产生正确的2
。
正确的解决方案取决于您在生产中使用的内容。
如果您正在使用MySQL,请在开发环境中将MariaDB替换为MySQL。在由自制软件管理的macOS机器上,它就像:
一样简单brew services stop mysql
brew uninstall mariadb
brew install mysql
brew services start mysql
您的数据将保持不变。
但是,如果您在制作中使用MariaDB,则需要重写查询以将JSON_EXTRACT()
函数用作Elias already mentioned。正如您所看到的,您需要使用Laravel API更加冗长。
以上查询将是:
SELECT JSON_EXTRACT(payload, "$.b") FROM test;
答案 1 :(得分:3)
我为json支持制作了Laravel MariaDB驱动程序。在此处获取:ybr-nx/laravel-mariadb
答案 2 :(得分:2)
问题是只有 MySQL 支持->
运算符,然后查询将在 MariaDB 上失败,但是:
MariaDB 和 MySQL 都支持JSON_EXTRACT
函数,该函数解析 JSON 并从中获取值。
您可以通过执行以下查询来解决此问题:
SELECT * FROM notifications WHERE JSON_EXTRACT(`notifications.data`, "$.id") = 5
要使用Laravel's Query Builder执行此操作,您需要使用DB::raw
方法:
DB::table('notifications')->where(DB::raw('JSON_EXTRACT(`notifications.data`, "$.id")'), '=', 3);
请尝试并告诉我是否出错。
注意: JSON_EXTRACT()
仅适用于MySQL >= 5.7
或MariaDB >= 10.2.3
谢谢到@Sepehr,我不知道->
是一个MySQL运算符,也不存在JSON类型。 : - )
答案 3 :(得分:0)
问题在于->
,我认为你有一个名为 $ data 的 var ,其中有一些集合。
如果是这样,那么正确的方法是:
DB::table('notifications')->where($data->id, '3')->get();
或者,如果您有与通知表相关的模型,则:
Notification::where($data->id, '3')->get();
如果Model
被称为Notification
(遵循Eloquent惯例)
但如果你试图找到所有ID等于3,那么只需:
DB::table('notifications')->where('id', '3')->get();