Laravel Eloquent 搜索 JSON 数组以获取特定列的值

Posted

技术标签:

【中文标题】Laravel Eloquent 搜索 JSON 数组以获取特定列的值【英文标题】:Laravel Eloquent search JSON array for a specific column's value 【发布时间】:2022-01-11 06:47:14 【问题描述】:

我有一个带有 readings (JSON) 字段的 Eloquent Book 模型。它是一个12个位置的数组,每个位置对应于当年每个月每本书的阅读次数,例如:

[1, 0, 3, 2, 5, 5, 2, 1, 3, 0, 0, 2]

在我的一个控制器中,我想按月选择所有具有一个或多个读数的书籍。所以我有一个for 循环,它会在几个月内迭代。以下是我的最佳尝试,但问题是 在任何迭代中 都没有选择任何书籍,尽管示例中的书籍应该在除 2、10 和 11 之外的所有迭代中返回:

for ($i = 1; $i <= 12; $i++) 
    $books = Book::whereJsonDoesntContain('readings->'. $i - 1, 0)->get();
    ...
;

我还尝试在 for 循环中使用 Book::whereRaw('not json_contains(readings-&gt;'.$i-1.', 0)');,但运气相同。

有什么想法吗? 提前致谢。

【问题讨论】:

根据documentation:“您可以使用whereJsonContains 查询JSON 数组。”由于您正在循环,您可以/应该使用普通的 where 查询,-&gt;where("readings-&gt;$i", '&gt;', 0) 感谢@zoispag,但您的答案不起作用,尽管它不会引发任何错误。 $books 再次返回空。正如我所见,使用 JSON 的处理方式不同。 【参考方案1】:

看起来whereJsonDoesntContain 应该可以工作——它在内部使用JSON_CONTAINS——但它转换了这段代码:

Book::whereJsonDoesntContain('readings->3', 0);

进入这个查询:

SELECT *
  FROM books
  WHERE NOT JSON_CONTAINS(`readings`, '0', '$."3")

问题在于路径无效; Laravel 假设传递的是对象键而不是数组键,其路径应类似于 $[3]

类似地,一个普通的where() 查询如下:

Book::where('readings->3', '!=', 0);

改为使用相同的无效路径。

SELECT *
  FROM books
  WHERE JSON_UNQUOTE(JSON_EXTRACT(`readings`, '$."3"')) != '0'

所以我们剩下的是使用JSON_EXTRACT 的原始查询:

for ($i = 0, $i <= 11; $i++) 
    $books = Book::whereRaw("JSON_EXTRACT(`readings`, '\$[$i]') != 0");

这应该返回您需要的记录;这个查询的测试小提琴是here


注意这个语法:

Book::whereJsonDoesntContain('readings->[3]', 0);

应该可以工作in Laravel 9.0

【讨论】:

谢谢@miken32,它成功了:)【参考方案2】:

您的查询应该是:

$books = Book::whereJsonDoesntContain('readings', 0)->get();

删除for 或任何循环...readings 是字段,在本例中为1, 0, 3, 2, 5, 5, 2, 1, 3, 0, 0, 2...

【讨论】:

我需要for 循环,因为除了$books 过滤之外,我还在循环中做一些其他事情... 问题是寻找每个月读过的书,这只会返回每个月读过的书。 @miken32 这是真的,我的错 @andcl 你必须知道哪一栏是什么时候读的?我的查询将有效,但适用于所有书籍......而且,您需要在循环中做什么?你需要解释更多...

以上是关于Laravel Eloquent 搜索 JSON 数组以获取特定列的值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Eloquent 在包含对象数组的 json 字段中进行搜索

在最近的关系记录中搜索 - Laravel (Eloquent)

Laravel/Eloquent 规范化 JSON 响应的关系?

Laravel Vue - 在 json 响应中获得 Eloquent

JSON Web Token 仅适用于具有 Eloquent 模型的 Laravel

Laravel Eloquent 模型 JSON 输出格式