Elasticsearch 分析器:配置、组件与应用详解
1. 希腊字母解析示例
在处理普通文本时,我们可以使用自定义分析器来解析希腊字母。例如,以下代码展示了如何使用自定义分析器
greek_letter_custom_analyzer
解析包含希腊字母的文本:
POST index_with_parse_greek_letters_custom_analyzer/_analyze
{
"text": "α and β are roots of a quadratic equation. γ isn't",
"analyzer": "greek_letter_custom_analyzer"
}
该自定义分析器会将希腊字母(如 α、β 和 γ)处理为对应的英文单词,输出结果为
"alpha","beta","gamma"
,而其他单词(如
roots
和
quadratic equation
)则会被移除。
2. 指定分析器
分析器可以在多个级别进行指定,包括索引级别、字段级别和查询级别。
2.1 索引时的分析器
在索引过程中,我们可能需要为不同的字段设置不同的分析器。
- 字段级别分析器 :在创建索引的映射定义时,我们可以在字段级别指定所需的分析器。例如:
PUT authors_with_field_level_analyzers
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"about":{
"type": "text",
"analyzer": "english"
},
"description":{
"type": "text",
"fields": {
"my":{
"type": "text",
"analyzer": "fingerprint"
}
}
}
}
}
}
在上述代码中,
about
和
description
字段指定了不同的分析器,而
name
字段隐式继承了标准分析器。
- 索引级别分析器 :我们还可以在索引级别设置默认的分析器。例如:
PUT authors_with_default_analyzer
{
"settings": {
"analysis": {
"analyzer": {
"default":{
"type":"keyword"
}
}
}
}
}
在这个例子中,我们将默认的标准分析器替换为关键字分析器。可以使用以下代码测试该分析器:
PUT authors_with_default_analyzer/_analyze
{
"name":"John Doe"
}
该代码将输出单个标记
"John Doe"
,且不进行小写转换或分词,这表明它是由关键字分析器进行分析的。
2.2 查询时的分析器
Elasticsearch 允许我们在查询时指定与索引时不同的分析器,并且可以在索引创建时设置整个索引的默认分析器。
- 查询中指定分析器 :在搜索查询中,我们可以显式指定分析器。例如:
GET authors_index_for_search_analyzer/_search
{
"query": {
"match": {
"author_name": {
"query": "M Konda",
"analyzer": "simple"
}
}
}
}
在这个例子中,我们在搜索作者时显式指定了分析器,该分析器很可能与
author_name
字段在索引时使用的分析器不同。
- 字段级别设置搜索分析器 :我们可以在字段级别设置搜索特定的分析器。例如:
PUT authors_index_with_both_analyzers_field_level
{
"mappings": {
"properties": {
"author_name":{
"type": "text",
"analyzer": "stop",
"search_analyzer": "simple"
}
}
}
}
在上述代码中,
author_name
字段在索引时使用
stop
分析器,而在搜索时使用
simple
分析器。
- 索引级别设置默认搜索分析器 :我们可以在索引创建时设置默认的搜索分析器。例如:
PUT authors_index_with_default_analyzer
{
"settings": {
"analysis": {
"analyzer": {
"default_search":{
"type":"simple"
},
"default":{
"type":"standard"
}
}
}
}
}
在这个例子中,我们同时设置了索引时的默认分析器和搜索时的默认分析器。
2.3 分析器的优先级顺序
当在不同级别定义了分析器时,引擎会按照以下优先级顺序选择合适的分析器:
1. 查询级别定义的分析器具有最高优先级。
2. 在定义索引映射时,通过设置
search_analyzer
属性在字段上定义的分析器。
3. 索引级别定义的分析器。
4. 如果以上都未设置,Elasticsearch 引擎将选择字段或索引上设置的索引分析器。
3. 字符过滤器
当用户进行搜索时,通常不会使用标点符号、特殊字符、HTML 标签或 XML 标签等。基于这些假设,我们可以使用字符过滤器来分析和清理输入的文本。字符过滤器可以帮助清除输入流中不需要的字符,它是分析器模块的第一个可选组件,一个分析器可以包含零个或多个字符过滤器。字符过滤器的具体功能如下:
- 从输入流中移除不需要的字符。例如,移除 HTML 标记。
- 向现有流中添加或替换字符。例如,将符号替换为对应的英文单词。
3.1 HTML 剥离过滤器
HTML 剥离过滤器可以移除输入字段中的 HTML 标签。例如:
POST _analyze
{
"text":"<h1>Where is my cheese?</h1>",
"tokenizer": "standard",
"char_filter": ["html_strip"]
}
该过滤器会将
<h1>
标签从输入字段中移除,生成
"Where", "is", "my", "Cheese"
标记。如果需要保留某些 HTML 标签,可以配置
html_strip
过滤器的
escaped_tags
数组。例如:
PUT index_with_html_strip_filter
{
"settings": {
"analysis": {
"analyzer": {
"custom_html_strip_filter_analyzer":{
"tokenizer":"keyword",
"char_filter":["my_html_strip_filter"]
}
},
"char_filter": {
"my_html_strip_filter":{
"type":"html_strip",
"escaped_tags":["h1"]
}
}
}
}
}
可以使用以下代码测试该自定义分析器:
POST index_with_html_strip_filter/_analyze
{
"text": "<h1>Hello,</h1> <h2>World!</h2>",
"analyzer": "custom_html_strip_filter_analyzer"
}
该代码将保留
<h1>
标签,输出结果为
"<h1>Hello,</h1> World!"
。
3.2 映射字符过滤器
映射字符过滤器的主要作用是将匹配的键替换为对应的值。例如:
POST _analyze
{
"text": "I am from UK",
"char_filter": [
{
"type": "mapping",
"mappings": [
"UK => United Kingdom"
]
}
]
}
如果需要创建一个带有映射字符过滤器的自定义分析器,可以按照以下步骤进行:
PUT index_with_mapping_char_filter
{
"settings": {
"analysis": {
"analyzer": {
"my_social_abbreviations_analyzer": {
"tokenizer": "keyword",
"char_filter": [
"my_social_abbreviations"
]
}
},
"char_filter": {
"my_social_abbreviations": {
"type": "mapping",
"mappings": [
"LOL => laughing out loud",
"BRB => be right back",
"OMG => oh my god"
]
}
}
}
}
}
可以使用以下代码测试该自定义分析器:
POST index_with_mapping_char_filter/_analyze
{
"text": "LOL",
"analyzer": "my_social_abbreviations_analyzer"
}
该代码将
"LOL"
替换为
"laughing out loud"
。
我们还可以通过文件提供映射关系,例如:
POST _analyze
{
"text": "FBI and CIA are USA's security organizations",
"char_filter": [
{
"type": "mapping",
"mappings_path": "secret_organizations.txt"
}
]
}
文件
secret_organizations.txt
必须位于 Elasticsearch 的配置目录中或提供其绝对路径。
3.3 模式替换字符过滤器
模式替换字符过滤器会在字段与正则表达式匹配时,将字符替换为新的字符。例如:
PUT index_with_pattern_replace_filter
{
"settings": {
"analysis": {
"analyzer": {
"my_pattern_replace_analyzer":{
"tokenizer":"keyword",
"char_filter":["pattern_replace_filter"]
}
},
"char_filter": {
"pattern_replace_filter":{
"type":"pattern_replace",
"pattern":"_",
"replacement":"-"
}
}
}
}
}
可以使用以下代码测试该自定义分析器:
POST index_with_pattern_replace_filter/_analyze
{
"text": "Apple_Boy_Cat",
"analyzer": "my_pattern_replace_analyzer"
}
该代码将输入字段中的下划线
_
替换为连字符
-
,输出结果为
"Apple-Boy-Cat"
。
4. 分词器
分词器的作用是根据特定标准将输入字段拆分为标记,通常是句子中的单个单词。Elasticsearch 有十几种分词器,每种分词器都根据其定义对字段进行分词。
4.1 标准分词器
标准分词器根据单词边界和标点符号对单词进行拆分,它会根据空白分隔符以及逗号、连字符、冒号、分号等标点符号对文本字段进行分词。例如:
POST _analyze
{
"text": "Hello,cruel world!",
"tokenizer": "standard"
}
该代码将输出三个标记:
"Hello", "cruel", "world"
。
标准分析器只有一个可以自定义的属性
max_token_length
,该属性用于生成指定大小的标记(默认大小为 255)。我们可以通过创建带有自定义分词器的自定义分析器来设置该属性,例如:
PUT index_with_custom_standard_tokenizer
{
"settings": {
"analysis": {
"analyzer": {
"custom_token_length_analyzer": {
"tokenizer": "custom_token_length_tokenizer"
}
},
"tokenizer": {
"custom_token_length_tokenizer": {
"type": "standard",
"max_token_length": 2
}
}
}
}
}
在这个例子中,我们将自定义分词器的
max_token_length
设置为 2 个字符。
总结
通过本文,我们详细了解了 Elasticsearch 中分析器的配置、组件和应用。分析器可以在索引级别、字段级别和查询级别进行指定,并且可以使用字符过滤器和分词器来处理输入文本。不同的分析器、字符过滤器和分词器适用于不同的场景,我们可以根据具体需求进行选择和配置。同时,我们还了解了分析器的优先级顺序,这有助于我们在复杂的场景中正确选择合适的分析器。
分析器配置流程
graph LR
A[开始] --> B[选择分析器级别]
B --> |索引级别| C[设置默认分析器]
B --> |字段级别| D[为字段指定分析器]
B --> |查询级别| E[在查询中指定分析器]
C --> F[创建索引并设置分析器]
D --> G[创建索引映射并指定字段分析器]
E --> H[编写查询并指定分析器]
F --> I[测试分析器]
G --> I
H --> I
I --> J[结束]
分析器优先级表格
| 优先级 | 分析器定义位置 |
|---|---|
| 1 | 查询级别定义的分析器 |
| 2 |
字段级别通过
search_analyzer
属性定义的分析器
|
| 3 | 索引级别定义的分析器 |
| 4 | 字段或索引上设置的索引分析器 |
Elasticsearch 分析器:配置、组件与应用详解
5. 深入理解分析器组件的协同工作
前面我们分别介绍了分析器的各个组件,包括字符过滤器、分词器,实际上它们在分析器中是协同工作的。一个完整的分析器流程通常是先经过字符过滤器处理,去除或替换不必要的字符,然后由分词器将文本拆分成标记。以下是一个简单的示例,展示了字符过滤器和分词器如何协同工作:
PUT index_with_combined_analyzer
{
"settings": {
"analysis": {
"analyzer": {
"my_combined_analyzer": {
"tokenizer": "standard",
"char_filter": ["my_html_strip", "my_mapping"]
}
},
"char_filter": {
"my_html_strip": {
"type": "html_strip"
},
"my_mapping": {
"type": "mapping",
"mappings": [
"UK => United Kingdom"
]
}
}
}
}
}
POST index_with_combined_analyzer/_analyze
{
"text": "<h1>I am from UK</h1>",
"analyzer": "my_combined_analyzer"
}
在这个示例中,输入的文本首先经过
my_html_strip
字符过滤器,去除 HTML 标签,然后经过
my_mapping
字符过滤器,将
UK
替换为
United Kingdom
,最后由标准分词器将处理后的文本拆分成标记。
6. 不同场景下分析器的选择与配置
不同的业务场景需要不同的分析器配置,以下是一些常见场景及对应的分析器选择建议:
6.1 文本搜索场景
在文本搜索场景中,用户通常希望搜索结果尽可能准确和全面。对于英文文本,可以使用
english
分析器,它会处理英文的停用词、词干提取等。例如:
PUT articles_index
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "english"
},
"content": {
"type": "text",
"analyzer": "english"
}
}
}
}
对于中文文本,可以使用专门的中文分析器,如
ik_max_word
或
smartcn
分析器。以
ik_max_word
为例:
PUT chinese_articles_index
{
"settings": {
"analysis": {
"analyzer": {
"ik_analyzer": {
"tokenizer": "ik_max_word"
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_analyzer"
},
"content": {
"type": "text",
"analyzer": "ik_analyzer"
}
}
}
}
6.2 精确匹配场景
在需要精确匹配的场景中,如身份证号码、订单号等,可以使用
keyword
分析器,它会将整个输入作为一个标记。例如:
PUT orders_index
{
"mappings": {
"properties": {
"order_id": {
"type": "keyword"
}
}
}
}
6.3 模糊匹配场景
在模糊匹配场景中,可以使用
simple
分析器或自定义分析器。
simple
分析器会将文本拆分成单词,并转换为小写。例如:
PUT products_index
{
"mappings": {
"properties": {
"product_name": {
"type": "text",
"analyzer": "simple"
}
}
}
}
7. 分析器性能优化
在实际应用中,分析器的性能可能会影响系统的整体性能。以下是一些分析器性能优化的建议:
7.1 减少不必要的字符过滤器和分词器
如果字符过滤器和分词器的配置过于复杂,会增加处理时间。因此,只使用必要的字符过滤器和分词器,避免过度配置。
7.2 缓存分析结果
对于一些频繁使用的分析器和输入文本,可以考虑缓存分析结果,减少重复处理。
7.3 选择合适的分词器
不同的分词器性能不同,根据实际需求选择合适的分词器。例如,对于简单的文本处理,标准分词器可能已经足够,不需要使用复杂的自定义分词器。
8. 分析器的动态更新
在某些情况下,我们可能需要动态更新分析器的配置。Elasticsearch 支持在不重启集群的情况下更新分析器。以下是一个动态更新分析器的示例:
PUT /_cluster/settings
{
"transient": {
"indices.analysis.analyzer.custom_analyzer.type": "custom",
"indices.analysis.analyzer.custom_analyzer.tokenizer": "standard",
"indices.analysis.analyzer.custom_analyzer.char_filter": ["new_html_strip"]
}
}
PUT /_ingest/pipeline/my_pipeline
{
"description": "My pipeline with updated analyzer",
"processors": [
{
"analyze": {
"field": "my_field",
"analyzer": "custom_analyzer"
}
}
]
}
分析器组件协同工作流程
graph LR
A[输入文本] --> B[字符过滤器1]
B --> C[字符过滤器2]
C --> D[分词器]
D --> E[输出标记]
不同场景分析器选择表格
| 场景 | 推荐分析器 | 说明 |
|---|---|---|
| 英文文本搜索 |
english
分析器
| 处理英文停用词、词干提取等 |
| 中文文本搜索 |
ik_max_word
或
smartcn
分析器
| 专门用于中文分词 |
| 精确匹配 |
keyword
分析器
| 将整个输入作为一个标记 |
| 模糊匹配 |
simple
分析器
| 将文本拆分成单词并转换为小写 |
总结与展望
通过对 Elasticsearch 分析器的深入学习,我们了解了分析器的配置、组件以及它们在不同场景下的应用。分析器是 Elasticsearch 中非常重要的一部分,合理配置分析器可以提高搜索的准确性和性能。
在未来的应用中,随着业务需求的不断变化,我们可能需要不断调整和优化分析器的配置。同时,随着 Elasticsearch 技术的不断发展,可能会出现更多强大的分析器组件和功能,我们需要持续关注并学习,以更好地应对各种复杂的搜索场景。
超级会员免费看

被折叠的 条评论
为什么被折叠?



