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 】


相关推荐: 《下一站江湖2》大雪山加入方法  @Team是什么?揭秘团队含义  一加 Ace 6V 快充无法启用_一加 Ace 6V 充电优化  汽水音乐在线听歌网页版 汽水音乐在线听歌网页版入口  太平年在哪个平台播出  风车动漫官网首页入口登录 风车动漫在线观看正版地址  解决J*aScript动态图片上传中ID重复问题:在同一页面显示多张独立图片  大熊猫抓取竹子的“大拇指”其实是什么?蚂蚁庄园课堂今天答案最新11月30日  海外搜索引擎推广效果怎么样,怎么分析效果!  Win10如何关闭开机锁屏界面_Windows10跳过锁屏直接登录设置  Highcharts雷达图径向轴数值标签实现教程  windows10怎么关闭自动安装应用_windows10禁止推广应用下载  Win11怎么设置分辨率 Win11显示设置调整分辨率及刷新率修改  SQL聚合查询、联接与筛选:GROUP BY 子句的正确使用与常见陷阱  J*a中的值传递到底指什么_值传递模型在参数传递中的真正含义说明  Python对象引用与属性赋值:理解链表中的行为  实时数据流中高效查找最小值与最大值  Sublime怎么配置YAML文件格式化_Sublime YAML Formatter插件教程  Google Drive API 认证:服务账户与OAuth 2.0的选择与实践  如何通过settings.json个性化您的VS Code体验  中大网校app做题记录清除方法  手机耗电快是什么原因 延长手机电池续航时间的设置方法【详解】  vivo浏览器怎么离线保存网页 vivo浏览器下载完整页面以便无网络时阅读  《sketchbook》选中部分图案移动方法  PHP utf8_encode 字符编码转换疑难解析与最佳实践  猫眼电影app如何筛选支持退改签的影院_猫眼电影退改签影院筛选方法  mail.qq.com登录入口 QQ邮箱网页版直达  电脑从睡眠中被自动唤醒怎么办_Windows唤醒源事件查看与禁用【解决】  荣耀Magic7拍照夜景噪点处理_荣耀Magic7相机优化  解决Flex容器横向滚动内容截断与偏移问题  抖音网页版官方链接 抖音网页版官网链接入口  猫眼app抢票快还是小程序快  路由器DNS怎么设置最快 优化DNS提升上网速度教程  背部总是隐隐作痛怎么回事 背痛如何改善  抖音怎么解除第三方绑定_抖音解除第三方平台绑定方法介绍  《浙里办》电子发票开具方法  行者app怎样导出日志  C++ optional用法详解_C++17处理可能为空的返回值  实现二叉树的层序插入:基于树大小的路径导航  《原神》月之一版本新增书籍一览  C++如何实现单例模式_C++线程安全的单例模式写法  疯狂小鸟微信小游戏入口 疯狂小鸟网页版秒玩  Win10怎么设置快速启动 Win10开启快速启动设置方法  sublime怎么在文件中显示代码结构大纲_sublime符号列表功能  oppo手机如何通过下拉通知栏截图_oppo手机通知栏快捷截图方法  qq邮箱怎么注册_QQ邮箱注册步骤与注意事项  J*aScript模拟悬停与点击:自动化网页动态元素交互指南  青橙手机语音助手怎么唤醒_青橙手机语音助手设置与唤醒方法  TikTok搜索结果不显示怎么办 TikTok搜索刷新与优化方法  如何快速去除厨房重油污? 2025年最好用的厨房清洁剂推荐 

 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.