对包含 JSON 数组的 JSON 字段进行 Laravel 5.4 查询
Posted
技术标签:
【中文标题】对包含 JSON 数组的 JSON 字段进行 Laravel 5.4 查询【英文标题】:Making a Laravel 5.4 query on a JSON field containing a JSON array 【发布时间】:2018-06-09 12:51:00 【问题描述】:我正在尝试查询包含值数组的 JSON 字段。 例如,我们将表命名为“User”和字段“Friends”。 Friends 字段如下所示:
[
"id": 1,
"img": "img-1.jpg",
"name": "Name 1"
,
"id": 2,
"img": "img-2.jpg",
"name": "Name 2"
,
"id": 3,
"img": "img-3",
"name": "Name 3"
]
所以我想做的是在 User 表上查询 Friends 字段中 ID 等于 3 的所有内容。
类似:User::where('friends->id', 3)->orderBy('id', 'desc')->get();
当然,如果字段不包含数组,上面的例子就完美了,所以如果它只是:
"id": 1,
"img": "img-1.jpg",
"name": "Name 1"
绝望,即使我知道这不是很合乎逻辑,我也尝试过使用“whereIn”:User::whereIn('friends->id', [3])->get()
。或类似:User::where('friends->[0]->id', 3)->get()
、User::where('friends->[*]->id', 3)->get()
、User::where('friends->*->id', 3)->get()
。
我也尝试过 JSON_CONTAINS 或 JSON_SEARCH :User::whereRaw('JSON_CONTAINS(friends->"$.id", "3")')->get()
和许多不同的变体,但没有任何效果。
在来这里之前,我已经阅读了一些关于这个问题的有趣文章(它们在下面列出),但我似乎是唯一一个在 mysql 数据库中存储 JSON 数组的人,这怎么可能? ^^
https://mattstauffer.com/blog/new-json-column-where-and-update-syntax-in-laravel-5-3/ https://themsaid.com/laravel-mysql-json-colum-fast-lookup-20160709 http://www.qcode.in/use-mysql-json-field-in-laravel/因此,如果有人可以帮助我解决这个问题,我将不胜感激。 旁注:我当前的 MySQL 版本是 5.7.11,所以它确实支持 JSON 字段并且 Laravel 不会抛出任何错误,它只是返回一个空数组。
【问题讨论】:
【参考方案1】:您的whereRaw
尝试非常接近。如果您要存储单个对象,您的路径将是$.id
。但是,由于您要存储对象数组,因此您的路径是$[*].id
。这应该适合你:
User::whereRaw('JSON_CONTAINS(friends->"$[*].id", "3")')->get();
friends->"$[*].id"
选择器(它只是JSON_EXTRACT()
的快捷方式)将返回一个 ids 的 json 数组。然后JSON_CONTAINS()
将检查该 json 数组是否包含指定的 id。
另一种选择是构建一个用于JSON_CONTAINS()
的 json 搜索字符串。例如,这个查询也应该有效:
User::whereRaw('JSON_CONTAINS(friends, \'"id": 3\')')->get();
这避免了第一次调用JSON_EXTRACT()
,所以你只调用了一个json方法。我不知道哪个版本实际上会更快,或者是否会有任何区别。
另外,在与JSON_SEARCH()
相关的旁注中,此功能仅在您搜索字符串值时才有效。由于您的 json 显示 id 表示为整数而不是字符串,因此 JSON_SEARCH()
将不起作用。 MySQL 声称这是有意的行为(bug 79233 和 dup bug 79316)。
仅供参考,here is the documentation for the json search methods。
【讨论】:
你先生,让我很开心!非常感谢。 您的两种解决方案都有效,我可能会使用后一种,因为我发现它更优雅、更类似于 JSON,并且只需要一种 json 方法。再次感谢您非常直截了当但完整的回答。 从 Laravel 5.6.24 开始,可以使用whereJsonContains()
:User::whereJsonContains('friends', ['id' => 3])->get();
以上是关于对包含 JSON 数组的 JSON 字段进行 Laravel 5.4 查询的主要内容,如果未能解决你的问题,请参考以下文章
python中怎么对json数组按json的某个字段进行排序
mysql数据库中某个字段存的是json数据,如何对json数据中的数据进行操作?
mysql数据库中,如何对json数据类型的值进行修改?通过json_set函数对json字段值进行修改?