Symfony Repository模糊搜索因大小写敏感导致查询无结果的问题
解决Symfony中LIKE模糊搜索大小写敏感问题的方案
出现该问题的核心原因是,数据库的LIKE匹配规则完全受字段排序规则控制,和PHP端拼接%search%的写法本身无关——当字段使用区分大小写的排序规则(如MySQL的utf8mb4_bin、PostgreSQL默认的排序规则)时,就会出现输入小写关键词匹配不到存储的大写/混合大小写内容的情况。
无数据库结构调整的跨库兼容改法
适配所有Doctrine支持的数据库(MySQL、PostgreSQL、SQLite),不需要改动现有表配置,直接修改Repository层的查询逻辑即可:
- 对所有参与匹配的数据库字段,使用
LOWER()函数强制转为小写后参与比对 - 将用户输入的搜索关键词同步转为小写,再拼接为模糊匹配的参数值
修改后的完整搜索方法代码:
public function search(string $search) { $search = trim($search); if (!$search) { return null; } $query = $this->createQueryBuilder('customers'); return $query->where('LOWER(customers.name) LIKE :search OR LOWER(customers.lastname) LIKE :search OR LOWER(customers.company_name) LIKE :search') ->setParameter('search', '%'.strtolower($search).'%') ->getQuery() ->getResult(); }
改完后无论用户输入的关键词是全大写、全小写还是混合大小写,只要字符匹配就能正常返回结果,完全规避数据库默认排序规则带来的匹配偏差。
性能更优的数据库层根治方案
如果项目基于MySQL开发,可以直接调整对应搜索字段的排序规则,将字段的字符集排序规则修改为带_ci(不区分大小写)后缀的规则,例如utf8mb4_0900_ai_ci:
- 调整完成后不需要修改Repository层代码,原生LIKE查询就会默认按不区分大小写的规则匹配
- 这种方式不会因为给字段套函数导致索引失效,配合字段普通索引可以获得远高于代码层转换的搜索性能
注意:PostgreSQL的原生LIKE语法默认就是严格区分大小写的,无法靠调整排序规则达到不区分大小写的匹配效果,必须在查询层做大小写转换,或使用数据库自带的
ILIKE语法实现不区分大小写匹配。
内容的提问来源于stack exchange,提问作者Buğra Kara
相关产品推荐
相关产品推荐

