在Laravel的where子句中如何判断数组所有元素都包含在字符串字段中
解决方案
你需要遍历过滤数组,给每一个要匹配的元素单独加查询条件,确保type字段同时包含所有元素,以下是两种常用实现方案:
方案1:LIKE 模糊查询(适配所有数据库)
如果对匹配精度要求不高可以直接用普通模糊匹配:
$filter = ['modern', 'hot']; $results = Model::query() ->when(!empty($filter), function ($query) use ($filter) { foreach ($filter as $item) { // 匹配包含对应单词的记录 $query->where('type', 'like', "%{$item}%"); } }) ->get();
如果要避免出现部分单词匹配的问题(比如搜hot误匹配到hottest),可以利用空格分隔的特性优化:
$filter = ['modern', 'hot']; $results = Model::query() ->when(!empty($filter), function ($query) use ($filter) { foreach ($filter as $item) { // 给字段首尾补空格后统一匹配空格包裹的单词,避免部分匹配 $query->whereRaw("CONCAT(' ', type, ' ') LIKE ?", ["% {$item} %"]); } }) ->get();
方案2:FIND_IN_SET 精准匹配(MySQL 专属)
如果用的是MySQL数据库,可以直接用FIND_IN_SET函数实现更精准的匹配,性能也优于上面的LIKE方案:
$filter = ['modern', 'hot']; $results = Model::query() ->when(!empty($filter), function ($query) use ($filter) { foreach ($filter as $item) { // 先把空格替换为逗号,再用FIND_IN_SET匹配 $query->whereRaw("FIND_IN_SET(?, REPLACE(type, ' ', ',')) > 0", [$item]); } }) ->get();
优化建议
如果数据量较大、查询频率高,建议调整存储结构:
- 将
type字段改为JSON数组类型,直接用JSON包含查询性能更好 - 单独建立标签关联表,用多对多关联存储标签,后续过滤、统计的灵活性更高
内容的提问来源于stack exchange,提问作者Don40
相关产品推荐
相关产品推荐

