全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Laravel 查询 JSON 数组列:实现“至少包含一个指定值”的高效过滤

本文介绍在 laravel 8 中如何对关联表的 json 数组列(如 `location_ids`)进行查询,精准筛选出至少包含 `$locations` 数组中任一值的记录,并提供兼容性兼顾的两种实现方案。

在 Laravel 应用中,当使用 MySQL 存储 JSON 格式的数组(例如 ["1", "2", "5"])并需基于用户权限动态过滤数据时,常见的需求是:判断 JSON 列是否与给定 PHP 数组存在交集(即“至少包含一个值”)。由于 JSON 列中存储的是字符串型数字(如 "1"),而 $locations 是整型数组(如 [1, 3, 7]),直接比对需注意类型一致性。

✅ 推荐方案一:JSON_OVERLAPS()(MySQL 8.0.17+,推荐优先使用)

JSON_OVERLAPS() 是 MySQL 原生函数,语义清晰、性能优异,且天然支持类型自动转换(可安全匹配整数与字符串数字):

public function scopeViewable($query)
{
    $user = Auth::user();
    $locations = $user->getShopAccess()->pluck('id')->values(); // 确保索引连续,避免 toJson() 出错

    if ($user->hasPermissionTo('users.index')) {
        return $query->whereHas('shopAccess', function (Builder $q) use ($locations) {
            $q->whereRaw('JSON_OVERLAPS(location_ids, ?)', [$locations->toJson()]);
        });
    }

    return $query->whereHas('shopAccess', function (Builder $q) use ($locations) {
        $q->where(function ($sub) use ($locations) {
            foreach ($locations as $location) {
                $sub->orWhereJsonContains('location_ids', (string) $location); // 显式转为字符串以匹配 JSON 中的 "1"
            }
        });
    });
}
⚠️ 注意:JSON_OVERLAPS() 要求 MySQL ≥ 8.0.17;若部署环境版本较低,请降级使用方案二。

✅ 方案二:循环 whereJsonContains()(全版本兼容)

适用于所有支持 JSON_CONTAINS 的 MySQL 版本(5.7+)。关键点在于:将整型 ID 显式转为字符串,以匹配 JSON 中的 "1" 而非 1:

$q->where(function ($sub) use ($locations) {
    foreach ($locations as $location) {
        $sub->orWhereJsonContains('location_ids', (string) $location);
    }
});

该写法生成类似以下 SQL:

WHERE JSON_CONTAINS(location_ids, '"1"') 
   OR JSON_CONTAINS(location_ids, '"3"') 
   OR JSON_CONTAINS(location_ids, '"7"')

? 补充说明与最佳实践

  • 避免 N+1 问题:确保 shopAccess 关系已正确定义(如 belongsToMany(Shop::class)),并在调用处预加载(with('shopAccess'))以提升性能。
  • 空数组保护:若 $locations 可能为空,建议前置校验:
    if ($locations->isEmpty()) {
        return $query->whereRaw('0'); // 返回空结果集
    }
  • 索引优化:MySQL 对 JSON_CONTAINS 和 JSON_OVERLAPS 的查询可利用生成列 + 普通索引加速(需额外建模,此处略)。

综上,优先采用 JSON_OVERLAPS() 提升可读性与执行效率;兼容性要求高时,使用带类型转换的 whereJsonContains() 循环方案,二者均能准确满足“JSON 数组列至少包含一个指定值”的业务场景。


# mysql  # php  # laravel  # js  # json  # access  # ai  # sql  # 整型  # 字符串  # 循环  # class  # 类型转换  # 的是  # 两种  # 适用于  # 并在  # 较低  # 而非  # 可利用  # 为空  # 比对 


相关文章: 宝塔面板如何快速创建新站点?  百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?  如何在企业微信快速生成手机电脑官网?  如何在Ubuntu系统下快速搭建WordPress个人网站?  c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】  如何高效配置IIS服务器搭建网站?  ,怎么用自己头像做动态表情包?  Java解压缩zip - 解压缩多个文件或文件夹实例  如何通过虚拟机搭建网站?详细步骤解析  制作营销网站公司,淘特是干什么用的?  如何通过虚拟主机快速搭建个人网站?  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  如何选择最佳自助建站系统?快速指南解析优劣  建站之星安装模板失败:服务器环境不兼容?  名字制作网站免费,所有小说网站的名字?  上海网站制作开发公司,上海买房比较好的网站有哪些?  建站之星Pro快速搭建教程:模板选择与功能配置指南  如何基于PHP生成高效IDC网络公司建站源码?  如何续费美橙建站之星域名及服务?  潍坊网站制作公司有哪些,潍坊哪家招聘网站好?  如何获取上海专业网站定制建站电话?  如何通过西部建站助手安装IIS服务器?  如何高效完成独享虚拟主机建站?  制作电商网页,电商供应链怎么做?  如何在阿里云虚拟服务器快速搭建网站?  桂林网站制作公司有哪些,桂林马拉松怎么报名?  济南网站建设制作公司,室内设计网站一般都有哪些功能?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  如何零基础在云服务器搭建WordPress站点?  php8.4新语法match怎么用_php8.4match表达式替代switch【方法】  广州建站公司哪家好?十大优质服务商推荐  无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?  如何快速选择适合个人网站的云服务器配置?  如何在服务器上三步完成建站并提升流量?  制作证书网站有哪些,全国城建培训中心证书查询官网?  C#怎么创建控制台应用 C# Console App项目创建方法  建站主机选虚拟主机还是云服务器更好?  如何配置支付宝与微信支付功能?  在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?  网站制作费用多少钱,一个网站的运营,需要哪些费用?  建站主机助手选型指南:2025年热门推荐与高效部署技巧  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  网站制作网站,深圳做网站哪家比较好?  如何自定义建站之星模板颜色并下载新样式?  如何解决ASP生成WAP建站中文乱码问题?  网站专业制作公司有哪些,做一个公司网站要多少钱?  建站之星如何取消后台验证码生成?  网站制作企业,网站的banner和导航栏是指什么?  如何通过建站之星自助学习解决操作问题? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。