对包含 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_CONTAINSJSON_SEARCHUser::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数据中的数据进行操作?

Jquery怎么样对这种json格式的数据进行增删改查

mysql数据库中,如何对json数据类型的值进行修改?通过json_set函数对json字段值进行修改?

如何在包含具有 Eloquent 的对象数组的 json 字段中求和

Json 模式数组大小参考