1. 分词发生的阶段
在 Elasticsearch 中,分词(Text Analysis) 主要发生在两个阶段:
-
索引阶段(Index time)
- 文本被写入时,字段内容会经过分词器处理,生成一系列词项(terms),存储到倒排索引中。
- 举例:
"Elasticsearch is powerful"→[elasticsearch, is, powerful]
-
查询阶段(Search time)
- 查询语句(如 match 查询)会对输入文本再次分词,以便和索引中的倒排词项进行匹配。
- 举例:搜索
"powerful elasticsearch"→[powerful, elasticsearch]
注意:索引阶段和查询阶段的分词器可以不同,这样可以实现 写时规范化,读时灵活匹配。
2. 分词器的组成
Elasticsearch 的 分词器(Analyzer) 由三个部分组成:
-
Character Filters(字符过滤器)
- 在分词前对文本做预处理。
- 如:
html_strip:去掉 HTML 标签,处理<p>Hello World!</p>,输出为Hello World!。 - 如:
mapping:替换指定字符(如将 "™" 替换为 "trademark") - 如:
pattern_replace:正则替换
-
Tokenizer(分词器)
- 核心步骤,把字符串切分成单词,将预处理后的文本拆分为词项(Tokens),是分词的核心步骤。
每个 Analyzer 必须包含一个 Tokenizer Standard会按空格、标点切分。whitespace:仅按空格拆分keyword:不拆分,将整个文本作为一个词项ik_max_word(IK 分词器):中文细粒度拆分ik_smart(IK 分词器):中文粗粒度拆分
- 核心步骤,把字符串切分成单词,将预处理后的文本拆分为词项(Tokens),是分词的核心步骤。
-
Token Filters(词元过滤器)
- 对分出来的词进一步处理。
- 如:大小写归一化、去停用词、词干化(running → run)。
lowercase:转为小写(默认包含在 standard analyzer 中)stop:去除停用词(如 "the"、"的")synonym:同义词替换(如将 "quick" 替换为 "fast")stemmer:词干提取(如将 "running" 还原为 "run")
3. 分词器的分类
常见分词器:
-
内置分词器(Built-in Analyzers)
standard(默认,支持 Unicode 规则)simple(按非字母切分,全部小写)whitespace(仅按空格切分)keyword(不分词,整体作为一个 term)
-
语言分词器(Language Analyzers)
- 如
english、smartcn(中文)、ik_max_word/ik_smart(IK 插件)。
- 如
-
自定义分词器(Custom Analyzer)
- 用户可以指定 字符过滤器 + 分词器 + 词元过滤器 来定制分词逻辑。
4. 特定场景的自定义分词器案例
场景:搜索商品名称,需要大小写不敏感、去停用词、支持同义词。
PUT my_index
{
"settings": {
"analysis": {
"filter": {
"my_synonym_filter": {
"type": "synonym",
"synonyms": [
"iphone, apple phone",
"tv, television"
]
}
},
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"char_filter": ["html_strip"],
"tokenizer": "standard",
"filter": ["lowercase", "stop", "my_synonym_filter"]
}
}
}
},
"mappings": {
"properties": {
"product_name": {
"type": "text",
"analyzer": "my_custom_analyzer"
}
}
}
}
测试分词效果:
POST my_index/_analyze
{
"analyzer": "my_custom_analyzer",
"text": "Apple Phone is <b>Powerful</b>"
}
结果包含:[apple, phone, powerful]
5. Ngram 自定义分词器案例 (后续单独讲解)
场景:支持模糊搜索(如输入 "iph" 也能匹配 "iphone")。
PUT ngram_index
{
"settings": {
"analysis": {
"tokenizer": {
"my_ngram_tokenizer": {
"type": "ngram",
"min_gram": 2,
"max_gram": 5,
"token_chars": ["letter", "digit"]
}
},
"analyzer": {
"my_ngram_analyzer": {
"type": "custom",
"tokenizer": "my_ngram_tokenizer",
"filter": ["lowercase"]
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "my_ngram_analyzer",
"search_analyzer": "standard"
}
}
}
}
测试分词效果:
POST ngram_index/_analyze
{
"analyzer": "my_ngram_analyzer",
"text": "iphone"
}
结果可能包含:[ip, iph, ipho, iphon, ph, pho, phon, phone, ...]
6. 示例 DSL
插入和查询数据示例:
POST ngram_index/_doc
{
"name": "iphone 15 pro"
}
POST ngram_index/_doc
{
"name": "samsung galaxy"
}
GET ngram_index/_search
{
"query": {
"match": {
"name": "iph"
}
}
}
结果会命中 "iphone 15 pro"。
小结
- 分词器发生在 索引阶段 & 查询阶段。
- 分词器由 字符过滤器 + 分词器 + 词元过滤器组成。
- 分词器可分为 内置、语言、自定义三类。
- 自定义分词器可以结合 同义词、停用词、HTML 处理等场景。
- Ngram 分词器适合 模糊搜索、前缀/部分匹配场景。