4. Analyzer与分词:内置分词器介绍、自定义分词器、中文分词选型(IK, pinyin),分词对搜索的影响。
聊到 Elasticsearch,有个东西你绕不开——分词器(Analyzer)。
说白了,分词器就是决定「用户搜什么能命中」的关键。我见过不少团队,索引建得挺漂亮,查询语法也熟练,但搜索效果就是差。一查,问题全出在分词上。
嗯,这节课我们就把它彻底讲透。
4.1 内置分词器:开箱即用的那些家伙
Elasticsearch 自带了好几个分词器,大部分场景下够用。我个人习惯先拿它们快速验证,不够再定制。
| 分词器名称 | 工作原理 | 典型场景 |
|---|---|---|
| Standard | 按单词边界切分,小写化,去除标点 | 英文全文搜索(默认) |
| Simple | 按非字母字符切分,小写化 | 纯英文、无数字干扰的场景 |
| Whitespace | 仅按空格切分,不做小写化 | 精确匹配、代码片段搜索 |
| Keyword | 不切分,整个字段作为一个词条 | ID、标签、枚举值 |
| Pattern | 按正则表达式切分 | 自定义分隔符需求 |
| Stop | 类似 Simple,但会移除停用词 | 对噪音词敏感的场景 |
4.2 自定义分词器:自己动手,丰衣足食
内置的不够用?那就自己搭。自定义分词器其实就三个组件:Character Filters(字符过滤)、Tokenizer(分词器)、Token Filters(词条过滤)。
我举个例子。假设你要处理用户输入的手机号,希望去掉中间的横杠和空格,再转成小写。可以这样配:
PUT /my_index
{
"settings": {
"analysis": {
"char_filter": {
"my_char_filter": {
"type": "mapping",
"mappings": ["-=>", " =>"]
}
},
"tokenizer": {
"my_tokenizer": {
"type": "keyword"
}
},
"filter": {
"my_filter": {
"type": "lowercase"
}
},
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": ["my_char_filter"],
"tokenizer": "my_tokenizer",
"filter": ["my_filter"]
}
}
}
}
}
你看,整个过程就像搭积木。先过滤字符,再切分,最后处理词条。我在项目中经常用这个套路处理脏数据,效果立竿见影。
4.3 中文分词选型:IK 与 pinyin
中文分词是搜索的「灵魂」。你想想看,中文没有空格,词与词之间全靠猜。选错分词器,搜索体验直接崩盘。
4.3.1 IK 分词器:中文搜索的标配
IK 是目前最流行的中文分词器,支持两种模式:
- ik_smart:最粗粒度切分,速度最快。适合搜索场景。
- ik_max_word:最细粒度切分,会穷举所有可能组合。适合索引阶段,召回率高。
举个例子,对「中华人民共和国国歌」:
ik_smart输出:中华人民共和国、国歌ik_max_word输出:中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、共和、国歌
我个人习惯:索引用 ik_max_word,搜索用 ik_smart。这样既保证召回率,又避免搜索时产生太多噪音。
4.3.2 pinyin 分词器:拼音搜索的利器
你有没有遇到过用户搜「zhongguo」想找「中国」?或者搜「lj」想找「李健」?这就是拼音分词器的用武之地。
pinyin 分词器可以把汉字转成拼音,支持全拼、首字母、混合模式。配置示例:
PUT /my_index
{
"settings": {
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "ik_max_word",
"filter": ["pinyin_filter"]
}
},
"filter": {
"pinyin_filter": {
"type": "pinyin",
"keep_full_pinyin": true,
"keep_joined_full_pinyin": true,
"keep_original": true,
"limit_first_letter_length": 16,
"remove_duplicated_term": true
}
}
}
}
}
这里有个关键参数 keep_original,设为 true 表示保留原始汉字。否则你搜「中国」可能只匹配到拼音,汉字反而搜不到,那就尴尬了。
search_as_you_type 字段里,配合 IK 一起用,效果最好。
4.4 分词对搜索的影响:成也分词,败也分词
分词选得好不好,直接决定搜索的「准」和「全」。我总结了几条核心影响:
- 召回率:分词越细,能匹配到的文档越多。但噪音也越大。
- 精准度:分词越粗,匹配越精确。但可能漏掉相关文档。
- 性能:分词越细,索引越大,查询越慢。需要权衡。
- 排序:分词结果影响 TF/IDF 和 BM25 评分。词条越多,评分越分散。
举个例子。假设你有一个商品标题「华为 Mate 40 Pro 5G 手机」:
- 用 Standard 分词器:华为、Mate、40、Pro、5G、手机
- 用 IK 分词器:华为、Mate、40、Pro、5G、手机
- 用 IK + pinyin:华为、huawei、Mate、40、Pro、5G、手机、shouji
你看,同样的内容,不同分词器产生不同的词条。用户搜「华为手机」时,Standard 和 IK 都能命中,但搜「huawei」时,只有加了 pinyin 的才能命中。
4.5 实战建议:如何选择分词器
说了这么多,到底怎么选?我给出一个通用策略:
- 英文为主:直接用 Standard,省心。
- 中文为主:IK(ik_max_word 索引 + ik_smart 搜索)。
- 需要拼音搜索:IK + pinyin 组合,pinyin 放在搜索字段的
fields子字段中。 - 精确匹配:用 Keyword 分词器,或者设置
index: false的字段。 - 混合语言:自定义分词器,组合多种 filter。
嗯,最后提醒一句:分词器选型一定要在项目初期确定。等数据量上来了再改,那代价……你懂的。
GET /_analyze API 快速验证分词效果,不用建索引就能看结果。我每次调分词器都先用它跑一遍,省时省力。
好了,这节课就到这里。下一节我们聊聊 Mapping 设计,那又是一个大坑……