
本文深入探讨了在 Laravel Eloquent 中查询 JSON 数组字段中特定索引值的问题。针对 `whereJsonDoesntContain` 和普通 `where` 方法在处理 JSON 数组路径时的局限性,提供了使用 `whereRaw` 结合 MySQL 的 `JSON_EXTRACT` 函数的有效解决方案。同时,文章也指出了 Laravel 9.0 及更高版本对 JSON 数组路径查询的改进,为开发者提供了更简洁的语法。
在 Laravel 应用中,将复杂数据结构(如数组)存储在数据库的 JSON 字段中是一种常见做法。然而,当需要查询 JSON 数组中特定索引位置的值时,开发者可能会遇到一些挑战。例如,假设我们有一个 Book 模型,其中包含一个 readings 字段,它是一个存储每月阅读次数的 JSON 数组,格式如下:[1, 0, 3, 2, 5, 5, 2, 1, 3, 0, 0, 2]。现在,我们希望筛选出特定月份阅读次数不为零的图书。
直观地,我们可能会尝试使用 Laravel 提供的 whereJsonDoesntContain 或简单的 where 方法:
// 尝试使用 whereJsonDoesntContain
for ($i = 1; $i <= 12; $i++) {
$books = Book::whereJsonDoesntContain('readings->'. $i - 1, 0)->get();
// ...
}
// 尝试使用 whereRaw (与 whereJsonDoesntContain 内部实现类似)
for ($i = 1; $i <= 12; $i++) {
$books = Book::whereRaw('not json_contains(readings->'.$i-1.', 0)')->get();
// ...
}
// 尝试使用简单的 where
Book::where('readings->3', '!=', 0)->get();然而,这些尝试可能无法返回预期的结果。问题在于 Laravel 在内部将 readings-youjiankuohaophpcn3 这样的路径转换为 $."3"。这种语法适用于查询 JSON 对象中的键,但不适用于 JSON 数组中的索引。对于 JSON 数组,正确的路径语法应该是$[3]`。
为了正确地查询 JSON 数组中的特定索引值,我们需要利用数据库底层的 JSON 函数。MySQL 提供了 JSON_EXTRACT 函数,它允许我们通过正确的路径语法提取 JSON 文档中的元素。结合 Laravel 的 whereRaw 方法,我们可以构建出满足需求的查询:
use App\Models\Book;
// 循环遍历月份(0-11 代表一年中的12个月)
for ($i = 0; $i <= 11; $i++) {
// 构建查询,使用 JSON_EXTRACT 提取指定索引的值,并检查其是否不等于0
$books = Book::whereRaw("JSON_EXTRACT(`readings`, '\$[$i]') != 0")->get();
// 在这里处理 $books 集合,例如:
echo "Month " . ($i + 1) . " books with readings: " . $books->count() . "\n";
foreach ($books as $book) {
// var_dump($book->title);
}
}代码解释:
Easily find JSON paths within JSON objects using our intuitive Json Path Finder
30
这个 whereRaw 查询会生成类似 SELECT * FROM books WHERE JSON_EXTRACT(readings, '$[0]') != 0 的 SQL 语句,从而正确地从 JSON 数组中筛选出符合条件的记录。
值得注意的是,Laravel 框架在 9.0 版本中对 JSON 数组路径的查询支持进行了改进。从 Laravel 9.0 开始,whereJsonDoesntContain 等方法应该能够识别 readings->[3] 这样的数组路径语法。
// 适用于 Laravel 9.0 及更高版本
Book::whereJsonDoesntContain('readings->[3]', 0)->get();这意味着在较新版本的 Laravel 中,开发者可以使用更简洁、更符合 Eloquent 风格的语法来查询 JSON 数组,而无需依赖 whereRaw。然而,对于使用旧版本 Laravel 或需要兼容更广泛数据库环境的情况,whereRaw 结合 JSON_EXTRACT 仍然是可靠的通用解决方案。
在 Laravel Eloquent 中查询 JSON 数组的特定索引值,需要理解其底层 SQL 实现和路径语法。对于旧版 Laravel 或需要通用解决方案的场景,通过 whereRaw 结合 JSON_EXTRACT 和正确的数组路径('$[index]')是高效且可靠的方法。对于 Laravel 9.0 及更高版本,框架提供了更友好的 readings->[index] 语法支持,简化了开发流程。在选择查询策略时,应综合考虑数据库版本、性能需求和代码可维护性。
以上就是Laravel Eloquent 查询 JSON 数组中特定列的值的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号