Lar*el Eloquent 查询 JSON 数组字段中特定索引的值


laravel eloquent 查询 json 数组字段中特定索引的值

本文旨在解决 Lar*el Eloquent 在查询 JSON 数组字段中特定索引值时遇到的挑战。我们将深入探讨 Eloquent 默认 JSON 路径解析的局限性,特别是在处理数组索引时的不准确性,并提供两种有效的解决方案:针对 Lar*el 9.0 之前版本,推荐使用 whereRaw 结合 JSON_EXTRACT 手动构建正确的 SQL 路径;对于 Lar*el 9.0 及更高版本,则可利用其改进的 whereJsonDoesntContain 语法,实现更简洁的查询。

理解 Lar*el Eloquent 对 JSON 数组路径的限制

在 Lar*el 中,我们经常会遇到需要将数组数据存储在数据库的 JSON 字段中的场景。例如,一个 Book 模型可能有一个 readings 字段,用于存储一年中每个月的阅读量,其格式为一个包含 12 个整数的 JSON 数组,如 [1, 0, 3, 2, 5, 5, 2, 1, 3, 0, 0, 2]。

当我们需要查询特定月份(即数组的特定索引)阅读量不为零的书籍时,直观上可能会尝试使用 Eloquent 提供的 whereJsonDoesntContain 或 where 方法配合 -> 操作符,例如:

// 尝试查询第三个月(索引为 2)阅读量不为 0 的书籍
$books = Book::whereJsonDoesntContain('readings->2', 0)->get();
// 或者
$books = Book::where('readings->2', '!=', 0)->get();

然而,这些尝试往往无法返回预期的结果。问题在于 Lar*el 在将 readings->2 这样的路径转换为 SQL 语句时,会将其错误地解析为 JSON 对象的键路径,而非 JSON 数组的索引路径。

例如,Book::whereJsonDoesntContain('readings->2', 0) 会被转换为类似于以下 SQL 查询:

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

而 Book::where('readings->2', '!=', 0) 则可能转换为:

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

注意 SQL 路径中的 $"2"。这表示查询一个名为 "2" 的键,而不是数组中索引为 2 的元素。正确的 JSON 数组索引路径应该形如 $[2]。由于路径不正确,数据库无法找到匹配的元素,导致查询结果为空。

解决方案:使用 whereRaw 和 JSON_EXTRACT (适用于 Lar*el 9.0 之前版本)

为了绕过 Lar*el 默认的 JSON 路径解析限制,我们可以使用 whereRaw 方法,结合数据库原生的 JSON_EXTRACT 函数来手动构建正确的查询语句。JSON_EXTRACT 函数允许我们精确地指定 JSON 路径,包括数组索引。

iSlide PPT iSlide PPT

DeepSeek AI加持,输入主题生成专业PPT,支持Word/PDF等45种文档导入,职场汇报、教学提案轻松搞定

iSlide PPT 375 查看详情 iSlide PPT

以下是针对上述场景的解决方案,它在一个循环中查询每个月阅读量不为零的书籍:

for ($i = 0; $i <= 11; $i++) {
    // $i 代表月份的索引,从 0 到 11
    // 注意:在 SQL 字符串中,需要对 $ 符号进行转义,即 \$
    // 但在这个特定场景中,由于 $i 是 PHP 变量,它会被直接替换,
    // 因此路径字符串 '$\['.$i.']' 最终会生成正确的 JSON 路径,例如 '$[0]', '$[1]' 等。
    $books = Book::whereRaw("JSON_EXTRACT(`readings`, '$[{$i}]') != 0")->get();

    // 在此处处理每个月查询到的书籍
    // 例如:
    // echo "Month " . ($i + 1) . " books with readings: " . $books->count() . "\n";
}

代码解析:

  • JSON_EXTRACT(\readings`, '$[{$i}]')`: 这段 SQL 片段是核心。
    • readings 是我们的 JSON 字段名。
    • '$[{$i}]' 是正确的 JSON 路径表达式,其中 {$i} 会被 PHP 循环变量替换为当前的数组索引(例如 $[0]、$[1] 等)。
  • != 0: 检查提取出的值是否不等于 0。

这种方法直接利用了数据库的 JSON 函数,确保了路径的准确性,从而能够正确地查询 JSON 数组中的特定元素。

Lar*el 9.0 及更高版本的改进

值得一提的是,Lar*el 框架在 9.0 版本中引入了一项改进,允许在 whereJsonDoesntContain 等方法中直接使用数组索引语法。这意味着在 Lar*el 9.0 及更高版本中,你可以使用更简洁、更符合 Eloquent 风格的方式来解决这个问题:

// 适用于 Lar*el 9.0+
for ($i = 0; $i <= 11; $i++) {
    // 直接使用 'readings->['.$i.']' 作为路径
    $books = Book::whereJsonDoesntContain('readings->[' . $i . ']', 0)->get();

    // 在此处处理每个月查询到的书籍
}

通过在路径中使用方括号 [] 包裹索引,Lar*el 9.0+ 能够正确识别这是一个 JSON 数组索引,并生成正确的 SQL 路径(例如 $[2]),从而避免了手动使用 whereRaw 的复杂性。

注意事项

  1. 数据库兼容性: JSON_EXTRACT、JSON_CONTAINS 等 JSON 函数是特定于数据库的。本教程中的示例基于 MySQL 5.7 及更高版本。如果您使用 PostgreSQL,则需要使用其对应的 JSON 函数(如 ->> 或 #>> 运算符)。
  2. 性能考量: 尽管 JSON 字段提供了存储灵活性的便利,但在大型数据集上频繁对 JSON 字段的内部结构进行查询(尤其是使用 whereRaw 或 JSON_EXTRACT)可能会影响查询性能。数据库通常无法对 JSON 字段的内部结构进行有效索引。如果对 JSON 数组的特定元素有高频率、高性能的查询需求,可能需要重新评估数据模型,考虑将这些特定元素规范化到单独的列或表中。
  3. 数据类型: JSON_EXTRACT 提取出的值通常是字符串类型。在进行比较时,请确保数据类型匹配,或者进行适当的类型转换。在上述 != 0 的例子中,MySQL 会尝试进行隐式转换。

总结

在 Lar*el Eloquent 中查询 JSON 数组字段的特定索引值,需要特别注意 JSON 路径的正确构建。对于 Lar*el 9.0 之前的版本,推荐使用 whereRaw 结合数据库原生的 JSON_EXTRACT 函数,手动指定 $[$i] 这样的数组索引路径。而对于 Lar*el 9.0 及更高版本,框架通过改进 whereJsonDoesntContain 等方法的路径解析能力,允许我们直接使用 readings->[$i] 这样的语法,大大简化了查询。理解这些机制和版本差异,将帮助开发者更高效、准确地处理 Lar*el 中的 JSON 数据查询需求。

以上就是Lar*el Eloquent 查询 JSON 数组字段中特定索引的值的详细内容,更多请关注php中文网其它相关文章!


# 适用于  # 肇庆seo关键词排名  # seo的禁忌  # seo包括什么等形式  # 东莞全网营销seo推广  # 设计网站建设推广报价  # 主题商业街营销推广方案  # 牡丹相关产品营销推广  # 网站优化易下拉软件  # 好的关键词排名优化方法  # 兰州网站优化找哪家公司  # 隐式  # 则可  # 运算符  # mysql  # 推荐使用  # 但在  # 运行环境  # 转换为  # 每个月  # 更高  # 隐式转换  # ai  # json  # js  # laravel  # php 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: C#解析来自网络的XML流数据 实时错误处理与重试机制  163邮箱网页版官方登录入口 163邮箱网页版访问页面  有道AI翻译入口 智能写作官方网站入口  《气泡星球》兑换码礼包大全  如何自定义苹果手机铃声  顺丰官方查单号入口 顺丰快递单号查询官网入口  咸鱼怎么设置仅粉丝可见的动态_咸鱼动态粉丝可见设置方法  yy漫画登录页面官方入口_yy漫画在线阅读网址入口  139邮箱登录入口官网 139邮箱登录入口官网网址  《我的恋爱逃生攻略》中文名字输入方法  《随手记》关闭首页消息推送方法  如何取消数字签名  iPhone14开启Apple TV遥控设置  电脑没有声音了怎么办 电脑声音问题的全面排查与修复指南【详解】  如何快速去除厨房重油污? 2025年最好用的厨房清洁剂推荐  《虎扑》取消评分记录方法  b站怎么查看视频的码率_b站视频码率查看方法  J*a列表元素格式化输出教程  小米手机屏幕失灵乱跳怎么办 屏幕触控问题自检与临时解决方法【应急】  VS Code快捷键when上下文子句的妙用  mysql镜像配置如何恢复数据_mysql镜像配置数据恢复详细流程  sublime如何自定义文件类型图标_AFileIcon插件的主题切换与个性化配置  C#中的Record类型有什么优势?C# 9新特性Record与Class的用法区别  优化Asyncio嵌套函数调度:使用生产者-消费者模式实现并发流处理  《oppo商城》维修服务位置  Golang如何测试结构体方法_Golang reflect方法测试与调用技巧  Apple Music无故扣费引质疑  京东快递包裹信息查询入口 京东快递官方查询平台入口  Microsoft Edge网页字体太淡看不清怎么办_Microsoft Edge字体渲染优化技巧  C++如何实现矩阵乘法_C++二维数组矩阵运算代码示例  OTT月报 | 2025年9月智能电视大数据报告  Sublime Text怎么关闭自动完成_Sublime禁用Auto Complete设置  PHP与SQL实践:高效实现数据复制与特定列值修改  PHP页面重载时变量值不重置的实现方法  AO3中文版手机快速通道_AO3最新稳定链接更新  路由器DNS怎么设置最快 优化DNS提升上网速度教程  《飞猪旅行》购买汽车票方法  惠普电脑BIOS界面看不懂怎么办_HP电脑BIOS功能选项解读与设置  《真我》申请退款方法  126邮箱网页在线登录2025_126邮箱网页版入口官方地址  追剧达人如何发弹幕  海棠阅读网页版_进入海棠网页版在线阅读中心  漫蛙官网(首页入口)_漫蛙漫画稳定访问教程分享  J*aScript事件处理:优化键盘输入与表单提交的实践指南  动漫岛在线动漫网 动漫岛动漫在线观看官方入口  《淘票票》添加到苹果钱包教程  江苏大剧院会员卡购买步骤  《虎扑》关闭社区内容推荐方法  稻壳阅读器官方直达网址链接 稻壳阅读器文档阅读平台主页资源入口  《腾讯相册管家》注销账号方法 

 2025-11-18

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.