讲师中心 微信公众号
AI工具推荐 视频效率加速

Laravel Eloquent 查询 JSON 数组字段中特定索引的值

大晨君_9764

大晨君_9764

发布时间:2025-11-18 11:28:28

|

690人浏览过

|

来源于php中文网

原创

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

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

理解 Laravel Eloquent 对 JSON 数组路径的限制

在 Laravel 中,我们经常会遇到需要将数组数据存储在数据库的 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();

然而,这些尝试往往无法返回预期的结果。问题在于 Laravel 在将 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]。由于路径不正确,数据库无法找到匹配的元素,导致查询结果为空。

chartjs-reporter
chartjs-reporter

此技能用于在用户需要将结构化数据(查询结果、CSV 摘要、JSON 记录或 Python 字典/列表)转换为独立的 HTML 页面时使用。

下载

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

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

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

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 数组中的特定元素。

Laravel 9.0 及更高版本的改进

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

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

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

通过在路径中使用方括号 [] 包裹索引,Laravel 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 会尝试进行隐式转换。

总结

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

热门AI工具

更多
咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

857

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

855

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

2508

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

4401

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

6390

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

4236

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

7929

2025.08.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

1496

2026.03.04

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 192人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn