You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel MySQL LIKE通配符查询未返回预期匹配结果的问题排查

问题原因与解决方案

核心原因

你的查询逻辑是用LIKE "%{$q}%"匹配完整的关键词子串:当搜索“Open ter”时,数据库会查找字段中包含Open ter(空格+小写ter)的内容,但目标条目里是Open Terms(空格+大写Terms)——LIKE不会自动对关键词的中间部分做模糊匹配,它只会匹配你给定通配符范围内的完整子串。

虽然utf8mb4_general_ci排序规则支持大小写不敏感(比如ter能匹配Ter),但它不会让短字符串自动匹配更长的包含它的字符串(比如ter不会匹配Terms),这就是为什么搜“Open ter”找不到目标条目,但搜“Terms”可以的原因。

解决方案

根据你的实际需求,有两种常见处理方式:

1. 匹配所有关键词(适用于需要同时包含“Open”和“ter”的场景)

拆分关键词为独立子条件,要求字段同时包含所有关键词:

use Illuminate\Support\Facades\DB;

$keywords = array_filter(explode(' ', trim($q))); // 过滤空字符串
$query = Listing::select("name", "slug");

foreach ($keywords as $keyword) {
    $query->where(function ($subquery) use ($keyword) {
        // 用参数绑定避免SQL注入
        $subquery->where("name", "LIKE", DB::raw("CONCAT('%', ?, '%')"), [$keyword])
                 ->orWhere("introduction", "LIKE", DB::raw("CONCAT('%', ?, '%')"), [$keyword]);
    });
}

$data = $query->get();

2. 模糊匹配关键词片段(适用于“Open ter”要匹配“Open Terms”的场景)

把关键词中的空格替换为通配符%,让中间可以匹配任意字符:

use Illuminate\Support\Facades\DB;

$processedQuery = str_replace(' ', '%', trim($q));
$data = Listing::select("name", "slug")
            ->where("name", "LIKE", DB::raw("CONCAT('%', ?, '%')"), [$processedQuery])
            ->orWhere("introduction", "LIKE", DB::raw("CONCAT('%', ?, '%')"), [$processedQuery])
            ->get();

注意事项

不要直接将用户输入拼接到SQL语句中(比如原代码的%{$q}%),存在SQL注入风险,建议使用上面的参数绑定写法。

内容的提问来源于stack exchange,提问作者Benjamin Mwendwa Munyoki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:50:04