必须预处理汉字为拼音字段再检索:mysql fulltext不支持拼音搜索,需添加pinyin_title等字段存储拼音,配合laravel scout+meilisearch实现高效、容错的中文拼音检索。

直接用 MySQL FULLTEXT 无法按拼音搜索
MySQL 的 MATCH AGAINST 只认原始字段内容,不识别拼音——你搜 "zhongguo",哪怕数据库里存着“中国”,也完全匹配不上。这不是配置问题,是引擎根本没这个能力。
- 它不会自动把汉字转成拼音再建索引,也不会在查询时做反向拼音映射
- 即使你在应用层手动把关键词转成拼音再查,
WHERE title LIKE '%zhongguo%'这种模糊匹配效率极低,且无法处理多音字、简拼、声调容错等真实需求 - 想靠改 SQL 或加索引绕过去?行不通。FULLTEXT 对非拉丁字符的分词和权重机制,对中文本身就非常弱
必须先「拼音化」数据,再走全文检索流程
真正可行的路径只有一条:把汉字字段预处理为拼音(或拼音首字母),存进额外字段,再让搜索引擎或数据库基于这些拼音字段去检索。
- 例如:给
articles表加一个pinyin_title字段,值为"zhong-guo-ji-zhu";再加pinyin_initials存"zgjz" - 用
overtrue/laravel-pinyin在模型事件中自动填充:creating和updating时调用$this->pinyin_title = app('pinyin')->permalink($this->title) - 注意多音字场景:默认
permalink()用最常见读音,如需精准控制(比如“重庆”必须转chong-qing而非zhong-qing),得配自定义词典或用->convert()+ 手动映射
Laravel Scout + Meilisearch 是目前最省心的落地方案
自己维护拼音字段 + LIKE 查询容易崩,尤其数据量一过万,排序、分页、高亮就全得重写。Scout 抽象掉底层细节,Meilisearch 原生支持中文分词+拼音容错,配合预存拼音字段,效果立竿见影。
- 安装后,在模型里加
use Searchable;,并重写toSearchableArray(),显式塞入拼音字段:'pinyin_title' => $this->pinyin_title - 搜索时直接
Article::search('zhongguo')->get(),Meilisearch 会自动匹配pinyin_title字段,响应毫秒级 - 别跳过
scout:import同步——新数据入库后,拼音字段变了但没推到 Meilisearch,搜不到不是代码错,是索引没更新 - Docker 启动 Meilisearch 时记得加
-e MEILI_HTTP_ADDR=:7700 -e MEILI_MASTER_KEY=masterKey,否则 Laravel 连不上,报错是cURL error 7: Failed to connect
别忽略「搜索意图」带来的设计取舍
用户搜“zg”,到底是想查“中国”还是“张国荣”?拼音首字母缩写(abbr())和完整拼音(permalink())服务的是不同场景,混用会导致漏结果。
- SEO 友好 URL、后台管理搜索建议 → 用
permalink()(带连字符,可读性强) - 移动端快速输入联想、姓名首字母筛选 → 用
abbr($str, '')得到"zg",但务必开启 Meilisearch 的typoTolerance防手误 - 如果业务强依赖多音字准确率(如法律文书、人名库),别只靠库的默认词典——得自己维护
custom_dict.php,把“长”、“行”、“乐”等字的业务常用读音固化进去
拼音不是简单的一次性转换,它是搜索链路里承上启下的中间表示。字段怎么存、何时更新、搜什么形式,每一步都得跟着真实用户输入习惯来定,而不是看文档示例写了啥就照搬。










