Appearance
分词与分析器
什么是分词(Analysis)?
分词是全文检索的基础:把一段文本拆成一个个词(term),再建倒排索引。搜索时查询词也会经过同样的拆分,再与索引中的词匹配。分词由**分析器(Analyzer)**完成,一个分析器通常包含三部分:
- 字符过滤器(Character Filter):先对原始字符串做预处理(如去 HTML、映射字符)。
- 分词器(Tokenizer):把字符串切分成词元(token)序列。
- 词元过滤器(Token Filter):对词元再处理(如转小写、去停用词、同义词)。
内置分析器
Elasticsearch 自带多种分析器,常用有:
| 分析器 | 说明 |
|---|---|
| standard | 默认,按词切分、转小写,支持多语言,适合多数场景 |
| simple | 按非字母切分,并转小写 |
| whitespace | 按空白字符切分,不转小写 |
| keyword | 不切分,整段当作一个词 |
| stop | 在 simple 基础上去掉停用词(如 the、a) |
| pattern | 按正则切分 |
对中文,standard 通常会把中文按单字切分,效果往往不理想,所以中文场景常用 IK 分词器 等第三方分析器。
测试分析器:_analyze API
不用真正建索引,就能看某段文本会被分成哪些词:
http
GET _analyze
{
"analyzer": "standard",
"text": "Elasticsearch 入门教程"
}返回中会看到 tokens 数组,每个 token 有 token、start_offset、end_offset 等。也可以指定索引的某字段,使用该字段配置的 analyzer:
http
GET my_index/_analyze
{
"field": "title",
"text": "入门教程"
}中文分词与 IK 分词器
默认中文的问题
使用 standard 对“ Elasticsearch 入门教程 ”分词时,英文会按词分,中文往往被拆成单字(如“入”“门”“教”“程”),检索和相关性都不理想。
IK 分词器
IK Analyzer 是常用的中文分词插件,支持:
- ik_max_word:最细粒度切分,适合建索引(召回多)。
- ik_smart:较粗粒度,适合搜索或短句(减少噪音)。
安装(示例,以 ES 7.x/8.x 为例):
- 使用 Elasticsearch 插件命令:
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/vx.x.x/elasticsearch-analysis-ik-x.x.x.zip
(具体版本号见 IK releases) - 或下载 zip 解压到
plugins/ik,重启 ES。
安装后在 mapping 里指定 analyzer:
http
PUT /my_index
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}- analyzer:写入时用的分析器(建索引)。
- search_analyzer:查询时用的分析器(可省略,默认用 analyzer)。
自定义词典
IK 支持扩展词和停用词,在 plugins/ik/config/ 下可配置:
- IKAnalyzer.cfg.xml:指定扩展词典、远程词典等。
- 扩展词:把业务专有词加进去,避免被拆散。
- 停用词:过滤掉“的、了、是”等无检索意义的词。
自定义分析器
若内置和 IK 仍不满足需求,可在索引 settings 里自定义 analyzer,组合 character filter、tokenizer、token filter:
http
PUT /my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": ["html_strip"],
"tokenizer": "standard",
"filter": ["lowercase", "my_stop"]
}
},
"filter": {
"my_stop": {
"type": "stop",
"stopwords": ["a", "the"]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "my_analyzer"
}
}
}
}自定义分析器只能在创建索引时或索引模板里定义,不能对已有索引随意修改。