Laravel查询含数组的jsonb列 实现类似whereIn的任意元素匹配效果
实现JSON数组任意元素匹配的查询方案
你之前使用的JSON_CONTAINS函数默认要求目标JSON数组包含所有传入的元素,属于「同时满足」的AND逻辑,要实现「匹配任意一个即可」的类whereIn效果,根据你使用的数据库类型选择对应方案即可:
方案1:PostgreSQL数据库(jsonb类型默认常用场景)
PostgreSQL针对jsonb数组提供了?|操作符,专门用于判断数组是否包含传入列表中的任意一个元素,写法如下:
$services = \App\Models\Service::where('status', 'accepted') ->whereRaw('support_tags ?| ARRAY[' . str_repeat('?,', count($categories) - 1) . '?]', $categories) ->get();
注:这里使用参数绑定避免SQL注入风险,不要直接拼接数组内容到SQL语句中
方案2:MySQL 8.0.17及以上版本
MySQL 8.0.17开始支持JSON_OVERLAPS函数,只要两个JSON文档存在公共元素就会返回true,完全匹配需求:
$services = \App\Models\Service::where('status', 'accepted') ->whereRaw('JSON_OVERLAPS(support_tags, ?)', [json_encode($categories)]) ->get();
方案3:低版本MySQL兼容方案
如果你的MySQL版本低于8.0.17,可以通过循环判断每个标签是否存在的方式实现:
$services = \App\Models\Service::where('status', 'accepted') ->where(function ($query) use ($categories) { foreach ($categories as $tag) { $query->orWhereRaw('JSON_SEARCH(support_tags, "one", ?) IS NOT NULL', $tag); } }) ->get();
内容的提问来源于stack exchange,提问作者DannyXCII
相关产品推荐
相关产品推荐

