Laravel Eloquent如何查询JSON类型readings数组字段对应月份值不为0的书籍
问题原因
- 运算符优先级错误
PHP 中字符串连接符.的优先级高于减法运算符-,你写的'readings->'. $i - 1实际执行逻辑是('readings->' . $i) - 1,最终得到的是数值 0,完全不符合你要取第$i-1下标的预期。 - 筛选方法使用错误
whereJsonDoesntContain的作用是判断整个JSON字段中是否不包含指定值,不是判断「指定下标的值不等于0」。就算你下标写对了,这个方法也会把所有readings数组里任意位置出现0的记录都排除,和你的需求完全不符。
正确写法
通用兼容写法(支持所有Laravel版本 + MySQL 5.7+)
先提前计算好下标,通过 JSON_EXTRACT 读取指定位置的值做判断:
for ($i = 1; $i <= 12; $i++) { $index = $i - 1; $books = Book::whereRaw("JSON_UNQUOTE(JSON_EXTRACT(readings, '$[$index]')) >= 1")->get(); // 你的后续业务逻辑 }
如果是MySQL环境,还可以简化为简写语法:
$books = Book::whereRaw("readings->>'$[$index]' >= 1")->get();
Laravel 9+ 简洁写法
Laravel 9 及以上版本原生支持JSON数组下标的直接查询,写法更简洁:
for ($i = 1; $i <= 12; $i++) { $index = $i - 1; $books = Book::where("readings[$index]", '>=', 1)->get(); }
注意:建议先在
Book模型中为readings字段添加JSON类型转换,方便日常读写操作:protected $casts = [ 'readings' => 'array', ];
内容的提问来源于stack exchange,提问作者andcl
相关产品推荐
相关产品推荐

