悠悠楠杉
网站页面
正文:
在实际开发中,我们经常遇到这样的场景:用户想搜索"COVID-19疫苗"却输入了"COVID 19",或是查找"iPhone 14 Pro"时漏掉了空格。传统的精确查询会让这些潜在匹配项从指缝中溜走,而通配符搜索正是破解这一痛点的利器。
MySQL提供了LIKE操作符配合两个核心通配符:
1. % - 匹配任意数量字符(包括零个字符)
2. _ - 匹配单个字符
比如要查找所有以"Pro"结尾的产品:
SELECT * FROM products
WHERE name LIKE '%Pro';
但当我们面对"MacBook-Pro"这样的字符串时,简单的通配符可能失效。这时需要引入字符替换策略。
在Laravel中,我们可以通过查询构建器优雅地实现复杂通配符搜索。以下是处理连字符/空格的典型方案:
// 搜索处理器
public function searchProducts(Request $request)
{
$keyword = str_replace(['-', ' '], '_', $request->input('q'));
return Product::where('name', 'LIKE', '%'.$keyword.'%')
->orWhere('description', 'LIKE', '%'.$keyword.'%')
->get();
}
这个方案先将用户输入的连字符和空格统一替换为下划线,再利用_通配符进行模糊匹配。例如:
- 用户输入"Mac Book" → 转换为"Mac_Book"
- 数据库存在"Mac-Book" → 匹配成功
对于更复杂的场景,可以结合正则表达式和多个通配符模式:
$searchTerm = preg_replace('/[-\s]/', '%', $request->q);
$products = Product::where(function($query) use ($searchTerm) {
$query->where('title', 'LIKE', '%'.$searchTerm.'%')
->orWhere('specs', 'LIKE', '%'.$searchTerm.'%');
})->when($request->category, function($query, $category) {
$query->where('category_id', $category);
})->paginate(10);
这个方案实现了:
1. 将连字符/空格转换为通配符%
2. 支持多字段联合搜索
3. 可组合其他查询条件
4. 自动分页处理
虽然通配符搜索很强大,但要注意:
1. 前导通配符(如%term)会使索引失效
2. 大数据表建议结合全文索引
3. 可添加搜索缓存层
对于百万级数据表,推荐采用这样的复合方案:
// 先用精确查询缩小范围
$ids = Product::where('name', 'REGEXP', str_replace(' ', '[- ]?', $keyword))
->limit(1000)
->pluck('id');
// 再用通配符查询结果集
$results = Product::whereIn('id', $ids)
->where('name', 'LIKE', '%'.$keyword.'%')
->get();