26、Elasticsearch 分析器:配置、组件与应用详解

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 技术的不断发展,可能会出现更多强大的分析器组件和功能,我们需要持续关注并学习,以更好地应对各种复杂的搜索场景。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值