Laravel中searchSubmissions函数无法匹配全名搜索的问题
Laravel 搜索全名无法匹配的解决方案
你遇到的问题本质是当前代码把用户输入的完整字符串直接拿去匹配firstname或lastname字段——当输入"john peter"这类全名时,数据库里的firstname是"john"、lastname是"peter",自然找不到包含整个"john peter"的字段,所以查不到结果。下面给你两种可行的解决方案,你可以根据需求选择:
方案一:支持多关键词模糊匹配(灵活度高)
这个方案会把输入的全名按空格拆分成单个关键词,确保每个关键词都能匹配到名或姓,既能匹配全名,也能匹配部分关键词:
public static function searchSubmissions($request, $candidateIds = array(),$isscontact = NULL){ $querys = DB::table('submissions')->select('submissions.*'); $candidateName = $request->input('candidatename'); if (!empty($candidateName)){ $querys->join('candidates','candidates.candidateid','=','submissions.candidateid'); // 拆分关键词并过滤空值(避免连续空格导致的无效关键词) $keywords = array_filter(explode(' ', trim($candidateName))); // 给每个关键词添加匹配条件 foreach ($keywords as $keyword) { $querys->where(function ($q) use ($keyword) { $q->where('candidates.firstname', 'LIKE', "%{$keyword}%") ->orWhere('candidates.lastname', 'LIKE', "%{$keyword}%"); }); } $querys->where('submissions.status','1'); } $result = $querys->paginate(PAGELIMIT); return $result ; }
逻辑说明:
- 先清洗输入的名字,去掉首尾空格后按空格拆分成关键词数组;
- 遍历每个关键词,用闭包包裹条件,确保每个关键词都能匹配到
firstname或lastname; - 保留原有的状态过滤条件,只查询有效提交记录。
方案二:精准匹配全名组合(更贴合“全名搜索”需求)
如果希望只有当输入的内容刚好对应“名+姓”或“姓+名”时才匹配,可以用这个方案:
public static function searchSubmissions($request, $candidateIds = array(),$isscontact = NULL){ $querys = DB::table('submissions')->select('submissions.*'); $candidateName = $request->input('candidatename'); if (!empty($candidateName)){ $querys->join('candidates','candidates.candidateid','=','submissions.candidateid'); $keywords = array_filter(explode(' ', trim($candidateName))); if (count($keywords) >= 2) { // 输入两个及以上关键词时,匹配两种全名组合 $querys->where(function ($q) use ($keywords) { // 情况1:第一个关键词匹配名,第二个匹配姓 $q->where('candidates.firstname', 'LIKE', "%{$keywords[0]}%") ->where('candidates.lastname', 'LIKE', "%{$keywords[1]}%") // 情况2:第一个关键词匹配姓,第二个匹配名 ->orWhere(function ($q2) use ($keywords) { $q2->where('candidates.firstname', 'LIKE', "%{$keywords[1]}%") ->where('candidates.lastname', 'LIKE', "%{$keywords[0]}%"); }); }); } else { // 单个关键词时,沿用原逻辑匹配名或姓 $querys->where(function ($q) use ($keywords) { $q->where('candidates.firstname', 'LIKE', "%{$keywords[0]}%") ->orWhere('candidates.lastname', 'LIKE', "%{$keywords[0]}%"); }); } $querys->where('submissions.status','1'); } $result = $querys->paginate(PAGELIMIT); return $result ; }
额外优化建议:
如果你的候选人数据量比较大,建议给candidates表的firstname和lastname字段创建FULLTEXT全文索引,然后用MySQL的全文搜索语法来优化性能,比如:
// 先给candidates表创建FULLTEXT索引:ALTER TABLE candidates ADD FULLTEXT INDEX idx_name (firstname, lastname); $querys->whereRaw("MATCH(candidates.firstname, candidates.lastname) AGAINST(? IN BOOLEAN MODE)", [$candidateName]);
这种方式比LIKE模糊匹配效率高很多,而且支持更灵活的关键词匹配规则。
内容的提问来源于stack exchange,提问作者Siva Ganesh
相关产品推荐
相关产品推荐

