导读:本期聚焦于小伙伴创作的《Laravel如何查询JSON数组列实现至少包含一个指定值的高效过滤》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Laravel如何查询JSON数组列实现至少包含一个指定值的高效过滤》有用,将其分享出去将是对创作者最好的鼓励。

在Laravel项目开发中,经常会遇到字段存储为JSON数组的场景,比如用户表的tags字段存储用户的所有标签,订单表的attr字段存储商品属性集合,此时需要筛选出至少包含某个指定值的记录,就需要用到针对性的查询方法。

核心查询方法:whereJsonContains

Laravel的Eloquent查询构造器原生提供了whereJsonContains方法,专门用于JSON数组列的包含判断,该方法会自动适配不同数据库的语法,不需要开发者手动拼接原生SQL,是最推荐的用法。

基础用法示例

假设用户表users的tags字段是JSON数组格式,存储用户的标签,现在要查询所有包含标签「php」的用户,代码如下:

<?php
// 查询tags数组中包含php的记录
$users = AppModelsUser::whereJsonContains('tags', 'php')->get();

// 如果需要同时包含多个值,可以传递数组作为第二个参数
// 以下查询tags中同时包含php和laravel的记录
$users = AppModelsUser::whereJsonContains('tags', ['php', 'laravel'])->get();

不同数据库的支持情况

whereJsonContains方法对不同数据库的适配规则如下:

  • MySQL 5.7+、MariaDB 10.2+:原生支持JSON数组包含判断,生成的SQL会调用JSON_CONTAINS函数
  • PostgreSQL:使用@>操作符判断数组包含关系
  • SQL Server 2016+:使用JSON_VALUE结合OPENJSON实现判断

如果需要查看生成的具体SQL语句,可以通过toSql方法输出:

<?php
$sql = AppModelsUser::whereJsonContains('tags', 'php')->toSql();
// MySQL下生成的SQL类似:select * from `users` where json_contains(`tags`, ?)

其他实现方式的对比

手动拼接原生SQL

部分开发者会直接写原生SQL实现过滤,比如MySQL下使用JSON_CONTAINS函数:

<?php
$users = AppModelsUser::whereRaw("JSON_CONTAINS(tags, '" . json_encode('php') . "')")->get();

这种方式的问题在于:第一,需要手动处理参数转义,容易出现SQL注入风险;第二,不兼容其他数据库,如果项目后续切换数据库类型,需要修改所有相关查询代码,维护成本高。

使用like模糊匹配

还有开发者会用where结合like做模糊查询:

<?php
$users = AppModelsUser::where('tags', 'like', '%"php"%')->get();

这种方式存在明显缺陷:如果JSON数组中有「php_framework」这样的标签,也会被错误匹配到,而且无法判断数组结构,查询准确性低,同时like匹配无法使用JSON字段的索引,大数据量下查询性能很差,不推荐使用。

性能优化建议

如果JSON数组列的查询频率很高,建议给该列添加对应的索引提升查询速度:

  • MySQL 8.0+支持给JSON数组列添加多值索引,创建语法如下:
<?php
// 迁移文件中添加多值索引
Schema::table('users', function (Blueprint $table) {
    $table->index(['tags'], 'tags_index')->algorithm('btree');
    // 或者使用JSON数组专用索引
    $table->rawIndex('(CAST(tags AS CHAR(255) ARRAY))', 'tags_array_index');
});
  • PostgreSQL可以直接给JSONB类型的列创建GIN索引,查询效率会大幅提升

另外需要注意,whereJsonContains方法如果传入的第二个参数是数组,表示同时满足多个包含条件,如果需要满足任意一个值即可,需要链式调用多个whereJsonContains或者用orWhereJsonContains

<?php
// 查询tags中包含php或者包含laravel的用户
$users = AppModelsUser::where(function ($query) {
    $query->whereJsonContains('tags', 'php')
          ->orWhereJsonContains('tags', 'laravel');
})->get();

常见注意事项

第一,确认字段的存储格式是正确的JSON数组,如果存储的是JSON对象或者字符串,whereJsonContains方法会返回空结果,可以在查询前通过cast方法定义字段类型:

<?php
// User模型中定义
protected $casts = [
    'tags' => 'array',
];

第二,如果JSON数组中的元素是数字类型,查询时第二个参数要传数字而不是字符串,比如查询包含数字1的标签:

<?php
$users = AppModelsUser::whereJsonContains('tags', 1)->get();

第三,部分旧版本数据库不支持JSON数组查询,此时建议将JSON数组拆分为关联表存储,避免使用JSON格式存储需要频繁查询的数组数据,从数据结构层面提升查询效率。

LaravelJSON数组列查询whereJsonContains数据库查询优化Eloquent修改时间:2026-06-11 22:48:37

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。