一、简介
在 Elasticsearch 中,分词器(Analyzer) 是文本处理的核心组件,用于将文本拆分为词项(Terms),并对词项进行标准化处理。分词器在索引和搜索过程中起着至关重要的作用,直接影响搜索的准确性和性能。
二、分词器的组成
Elasticsearch 的分词器由以下三个部分组成:
- 字符过滤器(Character Filters):
- 在分词之前对原始文本进行预处理。
- 例如,去除 HTML 标签、替换特殊字符等。
- 分词器(Tokenizer):
- 将文本拆分为单独的词项(Tokens)。
- 例如,按空格分词、按标点符号分词等。
- 词项过滤器(Token Filters):
- 对分词后的词项进行进一步处理。
- 例如,小写转换、去除停用词、词干提取等。
三、分词器的工作流程
- 字符过滤:去除 HTML 标签。
- 输入:
Elasticsearch is powerful!
- 输出:Elasticsearch is powerful!
- 输入:
- 分词:按单词边界分词。
- 输出:[“Elasticsearch”, “is”, “powerful”]
- 词项过滤:
- 小写转换:[“elasticsearch”, “is”, “powerful”]
- 去除停用词:[“elasticsearch”, “powerful”]
- 提取词干:[“elasticsearch”, “power”]
三、内置分词器
Elasticsearch 提供了多种内置分词器,适用于不同的场景。以下是常用的内置分词器:
Standard Analyzer
- 默认分词器:如果没有指定分词器,Elasticsearch 会使用 Standard Analyzer。
- 组成:
- 字符过滤器:无。
- 分词器:standard。
- 词项过滤器:lowercase。
- 功能:
- 按单词边界分词。
- 转换为小写。
- 去除标点符号。
- 适用场景:通用文本分析。
- 示例:
- 输入:“Elasticsearch is powerful!”
- 输出:[“elasticsearch”, “is”, “powerful”]
Simple Analyzer
- 组成:
- 字符过滤器:无。
- 分词器:lowercase。
- 词项过滤器:无。
- 功能:
- 按非字母字符分词。
- 转换为小写。
- 适用场景:简单的文本分析。
- 示例:
- 输入:“Elasticsearch is powerful!”
- 输出:[“elasticsearch”, “is”, “powerful”]
- 组成:
Whitespace Analyzer
- 组成:
- 字符过滤器:无。
- 分词器:whitespace。
- 词项过滤器:无。
- 功能:
- 按空格分词。
- 不进行小写转换或其他处理。
- 适用场景:需要保留原始大小写和标点符号的文本分析。
- 示例:
- 输入:“Elasticsearch is powerful!”
- 输出:[“Elasticsearch”, “is”, “powerful!”]
- 组成:
Keyword Analyzer
- 组成:
- 字符过滤器:无。
- 分词器:keyword。
- 词项过滤器:无。
- 功能:
- 将整个文本作为一个词项。
- 不进行分词或处理。
- 适用场景:需要精确匹配的字段(如 ID、标签)。
- 示例:
- 输入:“Elasticsearch is powerful!”
- 输出:[“Elasticsearch is powerful!”]
- 组成:
Pattern Analyzer
- 组成:
- 字符过滤器:无。
- 分词器:pattern。
- 词项过滤器:lowercase(可选)。
- 功能:
- 使用正则表达式分词。
- 可以自定义正则表达式。
- 适用场景:需要自定义分词规则的文本分析。
- 示例:
- 输入:“Elasticsearch-is-powerful!”
- 输出:[“elasticsearch”, “is”, “powerful”]
- 组成:
Language Analyzers
- 组成:
- 字符过滤器:无。
- 分词器:standard。
- 词项过滤器:语言特定的过滤器(如停用词、词干提取)。
- 功能:
- 针对特定语言的分词器。
- 支持多种语言(如英语、中文、法语等)。
- 适用场景:多语言文本分析。
- 示例:
- 输入:“Elasticsearch is powerful!”
- 输出:[“elasticsearch”, “powerful”](去除了停用词 “is”)
- 组成:
Stop Analyzer
- 组成:
- 字符过滤器:无。
- 分词器:lowercase。
- 词项过滤器:stop。
- 功能:
- 按非字母字符分词。
- 转换为小写。
- 去除停用词。
- 适用场景:需要去除停用词的文本分析。
- 示例:
- 输入:“Elasticsearch is powerful!”
- 输出:[“elasticsearch”, “powerful”]
- 组成:
Fingerprint Analyzer
- 组成:
- 字符过滤器:无。
- 分词器:standard。
- 词项过滤器:lowercase, stop, fingerprint。
- 功能:
- 将文本转换为唯一的指纹。
- 去除重复词项和停用词。
- 适用场景:去重和标准化文本。
- 示例:
- 输入:“Elasticsearch is powerful and Elasticsearch is fast!”
- 输出:[“and”, “elasticsearch”, “fast”, “is”, “powerful”]
- 组成:
四、IK 分词器
在 Elasticsearch 中,IK 分词器(IK Analyzer) 是一个专门为中文文本设计的分词插件。它支持两种分词模式:智能模式(ik_smart) 和 最大分词模式(ik_max_word),能够高效地处理中文分词需求。
4.1 IK 分词器的特点
- 中文优化:专门为中文文本设计,支持中文分词。
- 两种分词模式:
- ik_smart:智能模式,尽可能组合词语,输出最少的词项。
- ik_max_word:最大分词模式,将文本切分为最细粒度的词项。
- 扩展词典支持:支持用户自定义词典,适应特定领域的分词需求。
- 高性能:基于字典的分词算法,分词速度快。
4.2 IK 分词器的安装
IK 分词器是一个第三方插件,需要手动安装到 Elasticsearch 中。
- 安装步骤
- 下载 IK 分词器的插件包(与 Elasticsearch 版本匹配)。
- 下载地址: https://github.com/infinilabs/analysis-ik/releases
- 将插件包解压到 Elasticsearch 的 plugins 目录下。
unzip elasticsearch-analysis-ik-{version}.zip -d /path/to/elasticsearch/plugins/ik
- 重启 Elasticsearch。
4.3 IK 分词器的配置
IK 分词器安装后,可以直接在索引设置或字段映射中使用。
- 在索引设置中配置 IK 分词器
PUT /my_index { "settings": { "analysis": { "analyzer": { "ik_smart_analyzer": { "type": "custom", "tokenizer": "ik_smart" }, "ik_max_word_analyzer": { "type": "custom", "tokenizer": "ik_max_word" } } } } }
- 在字段映射中指定 IK 分词器
PUT /my_index/_mapping { "properties": { "title": { "type": "text", "analyzer": "ik_smart_analyzer" }, "content": { "type": "text", "analyzer": "ik_max_word_analyzer" } } }
4.4 IK 分词器的使用
IK 分词器可以在索引和搜索时使用。
索引时分词
- 在索引文档时,IK 分词器会对文本字段进行分词。
POST /my_index/_doc/1 { "title": " Elasticsearch 是一个搜索引擎", "content": "IK 分词器非常好用" }
- 在索引文档时,IK 分词器会对文本字段进行分词。
搜索时分词
- 在搜索时,IK 分词器会对查询字符串进行分词。
POST /my_index/_search { "query": { "match": { "content": "分词器" } } }
- 在搜索时,IK 分词器会对查询字符串进行分词。
4.5 IK 分词器的测试
可以使用 _analyze API 测试 IK 分词器的效果。
测试 ik_smart 模式
POST /my_index/_analyze { "analyzer": "ik_smart", "text": "Elasticsearch 是一个搜索引擎" }
- 结果:
- 输入:“Elasticsearch 是一个搜索引擎”
- 输出:[“Elasticsearch”, “是”, “一个”, “搜索引擎”]
- 结果:
测试 ik_max_word 模式
POST /my_index/_analyze { "analyzer": "ik_max_word", "text": "Elasticsearch 是一个搜索引擎" }
- 结果:
- 输入:“Elasticsearch 是一个搜索引擎”
- 输出:[“Elasticsearch”, “是”, “一个”, “搜索”, “搜索引擎”, “索引”, “引擎”]
- 结果:
4.6 扩展词典
IK 分词器支持用户自定义词典,以适应特定领域的分词需求。
扩展词典的配置
- 在 config/analysis-ik/ 目录下创建自定义词典文件(如 my_dict.dic)。
- 在 IKAnalyzer.cfg.xml 中配置自定义词典:
<properties> <comment>IK Analyzer 扩展配置</comment> <entry key="ext_dict">my_dict.dic</entry> </properties>
- 重启 Elasticsearch。
自定义词典示例
- 词典内容:
搜索引擎 非常好用
- 测试结果:
- 输入:“Elasticsearch 是一个搜索引擎”
- 输出:[“Elasticsearch”, “是”, “一个”, “搜索引擎”]
- 词典内容:
4.7 停用词配置
IK 分词器支持配置停用词,以去除无意义的词项。
- 停用词配置
- 在 config/analysis-ik/ 目录下创建停用词文件(如 stopwords.dic)。
- 在 IKAnalyzer.cfg.xml 中配置停用词:
<properties> <comment>IK Analyzer 扩展配置</comment> <entry key="ext_stopwords">stopwords.dic</entry> </properties>
- 重启 Elasticsearch。
- 停用词示例
是 一个
- 测试结果:
- 输入:“Elasticsearch 是一个搜索引擎”
- 输出:[“Elasticsearch”, “搜索引擎”]
- 测试结果:
五、分词器的配置
分词器可以在以下位置配置:
索引设置(Index Settings):
- 在创建索引时定义分词器。
PUT /my_index { "settings": { "analysis": { "char_filter": { "my_char_filter": { "type": "mapping", "mappings": ["& => and"] } }, "filter": { "my_stopwords": { "type": "stop", "stopwords": ["is", "the"] }, "my_synonyms": { "type": "synonym", "synonyms": ["quick, fast"] } }, "analyzer": { "my_custom_analyzer": { "type": "custom", "char_filter": ["html_strip", "my_char_filter"], "tokenizer": "standard", "filter": ["lowercase", "my_stopwords", "my_synonyms", "stemmer"] } } } } }
- 配置说明
- char_filter:定义字符过滤器。
- my_char_filter:将 & 替换为 and。
- filter:定义词项过滤器。
- my_stopwords:去除停用词 is 和 the。
- my_synonyms:将 quick 和 fast 视为同义词。
- analyzer:定义自定义分词器。
- my_custom_analyzer:组合字符过滤器、分词器和词项过滤器。
- char_filter:定义字符过滤器。
- 在创建索引时定义分词器。
字段映射(Field Mapping):
- 为特定字段指定分词器。
PUT /my_index/_mapping { "properties": { "title": { "type": "text", "analyzer": "my_custom_analyzer" } } }
- 配置说明
- title 字段:使用自定义分词器 my_custom_analyzer。
- 为特定字段指定分词器。
搜索请求(Search Request):
- 在搜索时指定分词器。
POST /my_index/_search { "query": { "match": { "title": { "query": "Elasticsearch", "analyzer": "my_custom_analyzer" } } } }
- 配置说明
- match 查询:使用自定义分词器 my_custom_analyzer 分析查询字符串。
- 在搜索时指定分词器。
六、自定义分词器
如果内置分词器不能满足需求,可以通过组合字符过滤器、分词器和词项过滤器来自定义分词器,以实现更灵活的文本分析。
6.1 自定义分词器的配置
自定义分词器可以在索引设置中配置。以下是一个自定义分词器的配置示例:
PUT /my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"char_filter": ["html_strip"],
"tokenizer": "standard",
"filter": ["lowercase", "stop", "stemmer"]
}
}
}
}
}
配置说明
- type:指定分词器类型为 custom。
- char_filter:指定字符过滤器(如 html_strip)。
- tokenizer:指定分词器(如 standard)。
- filter:指定词项过滤器(如 lowercase, stop, stemmer)。
6.2 自定义分词器的使用
自定义分词器可以在索引映射或搜索请求中使用。
- 在索引映射中使用
- 在创建索引时,为特定字段指定自定义分词器:
PUT /my_index/_mapping { "properties": { "title": { "type": "text", "analyzer": "my_custom_analyzer" } } }
- 在创建索引时,为特定字段指定自定义分词器:
- 在搜索请求中使用
- 在搜索时,指定自定义分词器:
POST /my_index/_search { "query": { "match": { "title": { "query": "Elasticsearch", "analyzer": "my_custom_analyzer" } } } }
- 在搜索时,指定自定义分词器:
6.3 自定义分词器的测试
可以使用 _analyze API 测试自定义分词器的效果:
POST /my_index/_analyze
{
"analyzer": "my_custom_analyzer",
"text": "Elasticsearch is <b>powerful</b>!"
}
测试结果:
- 输入:“Elasticsearch is powerful!”
- 输出:[“elasticsearch”, “power”]
七、常用字符过滤器、分词器、词项过滤器
常用字符过滤器
- HTML Strip Char Filter:去除 HTML 标签。
- 示例:
Elasticsearch
→ Elasticsearch
- 示例:
- Mapping Char Filter:替换特定字符。
- 示例:将 & 替换为 and。
- Pattern Replace Char Filter:使用正则表达式替换字符。
- 示例:将 - 替换为空格。
- HTML Strip Char Filter:去除 HTML 标签。
常用分词器
- Standard Tokenizer:按单词边界分词。
- 示例:“Elasticsearch is powerful!” → [“Elasticsearch”, “is”, “powerful”]
- Whitespace Tokenizer:按空格分词。
- 示例:“Elasticsearch is powerful!” → [“Elasticsearch”, “is”, “powerful!”]
- Keyword Tokenizer:将整个文本作为一个词项。
- 示例:“Elasticsearch is powerful!” → [“Elasticsearch is powerful!”]
- Pattern Tokenizer:使用正则表达式分词。
-示例:按 - 分词:“Elasticsearch-is-powerful” → [“Elasticsearch”, “is”, “powerful”]
- Standard Tokenizer:按单词边界分词。
常用词项过滤器
- Lowercase Token Filter:将词项转换为小写。
- 示例:“Elasticsearch” → “elasticsearch”
- Stop Token Filter:去除停用词(如 “is”、“the”)。
- 示例:“Elasticsearch is powerful” → [“Elasticsearch”, “powerful”]
- Stemmer Token Filter:提取词干。
- 示例:“running” → “run”
- Synonym Token Filter:处理同义词。
- 示例:“quick” → [“quick”, “fast”]
- Lowercase Token Filter:将词项转换为小写。