全网整合营销服务商

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

免费咨询热线: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  # 类型转换  # 的是  # 两种  # 适用于  # 并在  # 较低  # 而非  # 可利用  # 为空  # 比对 


相关文章: 宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  孙琪峥织梦建站教程如何优化数据库安全?  如何在西部数码注册域名并快速搭建网站?  C#如何序列化对象为XML XmlSerializer用法  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  网站设计制作企业有哪些,抖音官网主页怎么设置?  宝塔建站助手安装配置与建站模板使用全流程解析  香港服务器WordPress建站指南:SEO优化与高效部署策略  南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?  如何在阿里云高效完成企业建站全流程?  小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建  定制建站策划方案_专业建站与网站建设方案一站式指南  建站之星IIS配置教程:代码生成技巧与站点搭建指南  建站主机SSH密钥生成步骤及常见问题解答?  如何快速搭建高效WAP手机网站吸引移动用户?  如何选择域名并搭建高效网站?  建站之星图片链接生成指南:自助建站与智能设计教程  济南网站制作的价格,历城一职专官方网站?  高端云建站费用究竟需要多少预算?  建站之星安装模板失败:服务器环境不兼容?  如何通过山东自助建站平台快速注册域名?  如何在云主机上快速搭建网站?  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  深圳 网站制作,深圳招聘网站哪个比较好一点啊?  如何通过FTP服务器快速搭建网站?  香港网站服务器数量如何影响SEO优化效果?  Android自定义控件实现温度旋转按钮效果  建站之星后台管理系统如何操作?  建站之星客服服务时间及联系方式如何?  视频网站app制作软件,有什么好的视频聊天网站或者软件?  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  网站制作需要会哪些技术,建立一个网站要花费多少?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  教程网站设计制作软件,怎么创建自己的一个网站?  如何在阿里云ECS服务器部署织梦CMS网站?  建站之星代理如何获取技术支持?  深圳网站制作案例,网页的相关名词有哪些?  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  企业网站制作公司网页,推荐几家专业的天津网站制作公司?  如何通过VPS建站无需域名直接访问?  网站制作公司广州有几家,广州尚艺美发学校网站是多少?  Python文件管理规范_工程实践说明【指导】  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  广州营销型建站服务商推荐:技术优势与SEO优化解析  简历在线制作网站免费版,如何创建个人简历?  小程序网站制作需要准备什么资料,如何制作小程序?  高端企业智能建站程序:SEO优化与响应式模板定制开发  ,网站推广常用方法?  建站之星2.7模板快速切换与批量管理功能操作指南 

您的项目需求

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