新闻中心
Lar*el Eloquent 查询 JSON 数组中特定列的值

本文深入探讨了在 Lar*el Eloquent 中查询 JSON 数组字段中特定索引值的问题。针对 `whereJsonDoesntContain` 和普通 `where` 方法在处理 JSON 数组路径时的局限性,提供了使用 `whereRaw` 结合 MySQL 的 `JSON_EXTRACT` 函数的有效解决方案。同时,文章也指出了 Lar*el 9.0 及更高版本对 JSON 数组路径查询的改进,为开发者提供了更简洁的语法。
理解 Lar*el Eloquent 查询 JSON 数组的挑战
在 Lar*el 应用中,将复杂数据结构(如数组)存储在数据库的 JSON 字段中是一种常见做法。然而,当需要查询 JSON 数组中特定索引位置的值时,开发者可能会遇到一些挑战。例如,假设我们有一个 Book 模型,其中包含一个 readings 字段,它是一个存储每月阅读次数的 JSON 数组,格式如下:[1, 0, 3, 2, 5, 5, 2, 1, 3, 0, 0, 2]。现在,我们希望筛选出特定月份阅读次数不为零的图书。
直观地,我们可能会尝试使用 Lar*el 提供的 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();然而,这些尝试可能无法返回预期的结果。问题在于 Lar*el 在内部将 readings->3 这样的路径转换为 $."3"。这种语法适用于查询 JSON 对象中的键,但不适用于 JSON 数组中的索引。对于 JSON 数组,正确的路径语法应该是$[3]`。
解决方案:使用 whereRaw 结合 JSON_EXTRACT
为了正确地查询 JSON 数组中的特定索引值,我们需要利用数据库底层的 JSON 函数。MySQL 提供了 JSON_EXTRACT 函数,它允许我们通过正确的路径语法提取 JSON 文档中的元素。结合 Lar*el 的 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);
}
}代码解释:
Perplexity
Perplexity是一个ChatGPT和谷歌结合的超级工具,可以让你在浏览互联网时提出问题或获得即时摘要
302
查看详情
- for ($i = 0; $i
- Book::whereRaw(...): 允许我们直接写入原始的 SQL 查询条件。
- JSON_EXTRACT(\readings`, '\$[$i]')`: 这是关键部分。
- ``readings```: 是数据库表中的 JSON 列名。
- '\$[$i]': 是 JSON_EXTRACT 函数的路径参数。
- $ 表示 JSON 文档的根。
- [ 和 ] 用于指定数组索引。
- $i 是循环变量,代表当前的数组索引。
- 请注意,由于 $i 是 PHP 变量,我们需要确保在 SQL 字符串中正确地拼接它。在双引号字符串中,$ 符号需要转义(\$),以避免 PHP 将其误认为是变量。
- != 0: 检查提取出的值是否不等于 0。JSON_EXTRACT 返回的值通常是字符串形式,MySQL 会在比较时进行类型转换。
这个 whereRaw 查询会生成类似 SELECT * FROM books WHERE JSON_EXTRACT(readings, '$[0]') != 0 的 SQL 语句,从而正确地从 JSON 数组中筛选出符合条件的记录。
Lar*el 9.0 及更高版本的改进
值得注意的是,Lar*el 框架在 9.0 版本中对 JSON 数组路径的查询支持进行了改进。从 Lar*el 9.0 开始,whereJsonDoesntContain 等方法应该能够识别 readings->[3] 这样的数组路径语法。
// 适用于 Lar*el 9.0 及更高版本
Book::whereJsonDoesntContain('readings->[3]', 0)->get();这意味着在较新版本的 Lar*el 中,开发者可以使用更简洁、更符合 Eloquent 风格的语法来查询 JSON 数组,而无需依赖 whereRaw。然而,对于使用旧版本 Lar*el 或需要兼容更广泛数据库环境的情况,whereRaw 结合 JSON_EXTRACT 仍然是可靠的通用解决方案。
注意事项与最佳实践
- 数据库版本兼容性: JSON_EXTRACT 和其他 JSON 函数在 MySQL 5.7+、PostgreSQL 9.3+ 等现代关系型数据库中得到支持。请确保您的数据库版本符合要求。
-
性能考虑: 对 JSON 字段进行查询,特别是涉及到 JSON_EXTRACT 等函数时,可能会比查询普通列的性能开销更大。数据库通常无法直接索引 JSON 字段的内部结构。如果您的应用需要频繁地查询 JSON 数组中的特定元素,并且数据量庞大,您可能需要考虑以下替代方案:
- 冗余存储: 将需要频繁查询的 JSON 数组元素提取到单独的数据库列中。
- 数据模型优化: 考虑将 JSON 数组中的每个元素建模为单独的关联表记录,实现数据规范化。例如,为每本书的每月阅读次数创建一个 book_readings 表。
- 路径转义: 在使用 whereRaw 构建 SQL 字符串时,务必注意路径中的特殊字符(如 $, [, ])的转义,以防止 SQL 注入或解析错误。在 PHP 的双引号字符串中,$ 需要用反斜杠转义。
-
类型转换: JSON_EXTRACT 返回的值通常是字符串。在进行比较操作时,数据库会尝试进行隐
式类型转换。如果需要严格的类型比较,可以使用 CAST 或 CONVERT 函数显式转换类型。
总结
在 Lar*el Eloquent 中查询 JSON 数组的特定索引值,需要理解其底层 SQL 实现和路径语法。对于旧版 Lar*el 或需要通用解决方案的场景,通过 whereRaw 结合 JSON_EXTRACT 和正确的数组路径('$[index]')是高效且可靠的方法。对于 Lar*el 9.0 及更高版本,框架提供了更友好的 readings->[index] 语法支持,简化了开发流程。在选择查询策略时,应综合考虑数据库版本、性能需求和代码可维护性。
以上就是Lar*el Eloquent 查询 JSON 数组中特定列的值的详细内容,更多请关注php中文网其它相关文章!
# php
# laravel
# js
# json
# mysql
# 南宁专业的seo价格
# 小黄鱼营销推广
# 网站建设单页设计
# 亚马逊公司网站推广方式
# 武进网站关键词优化
# 侯马外贸品牌网站建设
# seo查询为空
# 手串营销推广广告图片高清
# 企业为什么要seo
# 山东网站推广找哪家
# 可以使用
# 特殊字符
# 正确地
# 您的
# 隐式
# 数据结构
# 适用于
# 多条
# 更高
# 组中
# 隐式类型转换
# ai
# app
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
探索高级语言到原生C/C++的转译:挑战与内存管理策略
中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】
wps文字怎么插入目录并自动更新_wps文字如何插入目录并自动更新方法
如何在J*a中实现统一对象行为接口_项目大型化时的接口规范化
QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道
mysql备份恢复性能优化_mysql备份恢复性能优化方法
sublime侧边栏怎么增强功能_SideBarEnhancements for sublime安装与配置
Win11怎么关闭快速启动_Win11彻底关机设置教程
必由学官方平台入口 必由学在线课堂登录地址
夸克浏览器网页版最新地址 夸克浏览器官方入口合集
网易大神账号申诉需要多久_网易大神账号申诉流程说明
Yandex官方入口网址 Yandex俄罗斯搜索引擎最新在线地址
J*aScript实现单选按钮与关联输入框的联动禁用教程
如何提高微信支付的安全性_微信支付安全防护与设置建议
Win11怎么开启高性能模式_Windows 11电源计划优化设置
c++如何使用TBB库进行任务并行_c++ Intel线程构建模块
Mac终端命令大全_Mac常用Terminal指令速查
解决 MongoDB 聚合查询中对象数组 _id 匹配问题
漫蛙manwa2最新登录网址_漫蛙manwa2手机网页版入口
J*aScript map 方法中处理循环元素为空数组的策略
Win11怎么设置开机NumLock亮 Win11修改注册表InitialKeyboardIndicators值
Go语言中Map值调用指针接收器方法的限制与应对
在J*a中如何捕获IndexOutOfBoundsException_索引越界异常防护方法说明
《刺客信条:影》PS5 Pro和Switch 2画面对比
Python vgamepad库按键模拟:正确使用XUSB_BUTTON常量
J*a里如何使用N*igableMap进行导航操作_可导航Map操作技巧解析
在Qt QML中通过Python字典动态更新TextEdit内容的教程
163邮箱官方主页登录 直达网易邮箱登录核心页面
漫画星球免费下拉式入口 漫画星球免费漫画在线阅读网站
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全
电脑安装程序提示“错误1722”怎么办_Windows Installer服务问题解决【教程】
LINUX的perf命令入门_LINUX官方性能分析工具的使用与解读
PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符
Tabulator表格日期时间排序问题及自定义解决方案
CSS Box Model与弹性按钮:维持布局稳定的动画实践
新三国志曹操传110级星符试炼夏侯渊极难攻略
微信网页版官方入口教程 微信网页版网页版快速登录步骤
AO3官方镜像站点汇总 AO3同人作品网页版直达链接
PHP中SSG-WSG API的AES加密实践:正确使用初始化向量
J*a编写用户注册与登录功能_掌握字符串与验证逻辑
韩剧圈正版入口页面_韩剧圈官网登录链接
电脑IP地址怎么查 查看本机IP地址的几种方法
Win10自动更新怎么关闭 Win10永久关闭系统更新的两种方法【终极版】
微信网页版扫码登录入口 微信网页版二维码登录入口
12306选座如何查看座位示意图_12306座位示意图解读与使用
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
葱吃多了会怎样 葱吃多了会伤胃吗
QQ邮箱网页版邮箱入口 QQ邮箱官方登录平台
vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法


2025-11-14
浏览次数:次
返回列表
式类型转换。如果需要严格的类型比较,可以使用 CAST 或 CONVERT 函数显式转换类型。