ElasticSearch08-分析器详解

零、文章目录

ElasticSearch08-分析器详解

1、分析器原理

  • Elasticsearch的分词器(Analyzer)是全文搜索的核心组件,它负责将文本转换为一系列单词(term/token)的过程,也叫分词。
(1)分析器的构成
  • 字符过滤器(Character Filters)
    • 接收原始文本字符流,可以通过添加、移除或改变字符来转变原始字符流。例如,可以将印度-阿拉伯数字转换为阿拉伯-拉丁数字,或从流中去除HTML元素等。
  • 分词器(Tokenizer)
    • 接收字符流,将其分解为单独的tokens(通常是单个单词),并输出tokens流。例如,whitespace分词器在看到任何空格时将文本分解为tokens。它会将文本 "Quick brown fox!" 转换为多个terms [Quick, brown, fox!]。分词器还负责记录每个term的顺序或位置以及该term所代表的原始单词的开始和结束字符偏移量。
  • Token过滤器(Token Filters)
    • 接收令牌流,并且可以添加、删除或改变token。例如,lowercase token过滤器将所有token转换为小写,stop token过滤器从token流中删除常用词(停用词),而synonym token过滤器将同义词引入token流中。Token过滤器不允许更改每个token的位置或字符偏移量。
(2)分析器的工作流程
  • 字符过滤器处理:文本首先通过字符过滤器,进行预处理,如去除HTML标签或格式转换。
  • 分词器分词:经过预处理的文本进入分词器,分词器根据定义的规则(如空格、标点符号等)将文本拆分成单个词汇。
  • Token过滤器处理:分词后的词汇通过一系列的Token过滤器,进行进一步的处理,如小写化、停用词过滤、同义词扩展等。
  • 输出tokens:经过Token过滤器处理后的词汇成为最终的tokens,这些tokens将被用于构建倒排索引。
(3)分析器的重要性
  • 分词器对于Elasticsearch的全文搜索至关重要,因为它直接影响到搜索的准确性和相关性。不同的语言和文本类型可能需要不同的分词器来最有效地处理文本。
  • Elasticsearch提供了多种内置分词器,如standardsimplewhitespacestop等,以适应不同的应用场景。
  • 用户也可以根据需要自定义分词器,以满足特定的分词需求。

2、常见内置分词器

分词器名称 描述 示例文本 分词结果示例
Standard Tokenizer 使用Unicode文本分割算法,去除标点符号,适用于大多数欧洲语言 "Elasticsearch: Search & Analytics" "Elasticsearch", "Search", "Analytics"
Whitespace Tokenizer 以空白字符为分词符,包括空格和制表符 "Elasticsearch, search & analytics" "Elasticsearch,", "search", "\&", "analytics"
Lowercase Tokenizer 类似Whitespace Tokenizer,但将所有tokens转换为小写 "Elasticsearch, search & analytics" "elasticsearch,", "search", "\&", "analytics"
Keyword Tokenizer 不进行分词,将整个文本作为一个单独的token "Elasticsearch: Search & Analytics" "Elasticsearch: Search \& Analytics"
Pattern Tokenizer 使用正则表达式进行分词,默认为\W+(非单词字符) "Elasticsearch: Search & Analytics" "Elasticsearch", "Search", "Analytics"
N-Gram Tokenizer 创建n-grams,连续的字符序列 "elasticsearch"(2-gram) "el", "le", "ea", "ar", "rc", "ch", "ha", "an", "nt", "ts"
Edge N-Gram Tokenizer 从单词的开始或结束部分生成n-grams "elasticsearch"(1-gram,edge) "e", "l", "s", "e", "l", "a", "r", "c", "h"

3、分词器使用场景

(1)索引阶段(Indexing Phase)
  • **文档索引:**当文档被索引到Elasticsearch时,分词器用于将文本字段(如标题、内容等)转换为一系列tokens(词项)。这些tokens被存储在倒排索引中,以便后续搜索。
  • **分析器应用:**在索引过程中,指定的分析器(由分词器和token过滤器组成)会被应用到字段上,以确定如何将文本分割成tokens。
(2)查询阶段(Query Phase)
  • **查询解析:**当执行搜索查询时,Elasticsearch会对查询文本应用与索引时相同的分析器,包括分词器。这意味着查询文本也会被转换成tokens。
  • **查询处理:**查询的tokens与索引的倒排索引中的tokens进行匹配,以确定哪些文档包含这些tokens。
(3)相关性评分(Scoring Phase)
  • **评分计算:**在查询过程中,Elasticsearch会根据tokens在文档中出现的次数和频率计算相关性评分。分词器的使用确保了查询tokens与索引tokens的一致性,从而使得评分准确。
(4)聚合(Aggregations)
  • **术语聚合:**在执行基于术语的聚合(如terms聚合)时,分词器确保了聚合字段的tokens与查询tokens的一致性。
(5)高亮(Highlighting)
  • **结果高亮:**在搜索结果中,Elasticsearch会使用与索引相同的分析器对查询文本进行分词,以便在文档中高亮显示匹配的tokens。
(6)建议(Suggestions)
  • **自动完成和建议:**在自动完成或建议功能中,分词器用于处理用户输入的查询,以便与索引中的tokens匹配。
(7)同义词处理(Synonyms)
  • **查询扩展:**在使用同义词时,分词器可以与同义词过滤器结合使用,以便在查询时扩展tokens,包括同义词。

4、使用分词器

(1)默认分词器
  • Elasticsearch的默认分词器是standard分词器。这个分词器适用于大多数西方语言,特别是英文,它基于Unicode文本分割算法(Unicode Text Segmentation)来分割文本,并去除大多数标点符号。standard分词器在处理文本时会将所有单词转换为小写,以便进行不区分大小写的匹配。
  • 在创建新的索引时,如果不指定分词器,Elasticsearch会自动使用standard分词器来处理文本字段。例如,如果你创建了一个名为my_index的索引,并且没有指定分析器,那么my_index中的text字段将默认使用standard分词器。
  • 使用分词器进行分词,默认分词器无法解析中文词组,所以全部分词成单个字。
json 复制代码
# 请求
Get _analyze
{
    "text":"测试分词器"
}

# 返回
{
  "tokens" : [
    {
      "token" : "测",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "试",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "分",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    },
    {
      "token" : "词",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "<IDEOGRAPHIC>",
      "position" : 3
    },
    {
      "token" : "器",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "<IDEOGRAPHIC>",
      "position" : 4
    }
  ]
}
  • 中文分词指定中文 ik 分词器
json 复制代码
# 请求
Get _analyze
{
    "text":"测试分词器",
    "analyzer": "ik_max_word"
}

# 返回
{
  "tokens" : [
    {
      "token" : "测试",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "分词器",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "分词",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "器",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 3
    }
  ]
}
(2)创建索引并指定分析器
  • 我们创建了一个名为my_custom_analyzer的自定义分析器,它使用standard分词器,并且应用了lowercaseasciifolding过滤器。
  • 我们将text字段的分析器设置为定义的my_custom_analyzer
json 复制代码
# 请求
PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "analyzer": "my_custom_analyzer"
      }
    }
  }
}

# 返回
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "my_index"
}
(3)索引文档
  • text字段的值会被my_custom_analyzer处理,包括分词、小写化和ASCII折叠。
json 复制代码
# 请求
POST /my_index/_doc
{
  "text": "Elasticsearch is a distributed search engine."
}

# 返回
{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "mhUp05MBwu_sOZK4ykdt",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}
(4)执行搜索
  • 在这个搜索查询中,我们指定了my_custom_analyzer来处理查询字符串"Elasticsearch",确保查询时的分词和索引时的分词一致。
json 复制代码
# 请求
GET /my_index/_search
{
  "query": {
    "match": {
      "text": {
        "query": "Elasticsearch",
        "analyzer": "my_custom_analyzer"
      }
    }
  }
}

# 返回
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "mhUp05MBwu_sOZK4ykdt",
        "_score" : 0.2876821,
        "_source" : {
          "text" : "Elasticsearch is a distributed search engine."
        }
      }
    ]
  }
}
(5)注意事项
  • 分析器的选择对搜索结果有重要影响。正确的分析器可以帮助提高搜索的相关性和准确性。
  • 自定义分析器可以根据具体需求组合不同的分词器和过滤器。
  • 在创建索引后,分析器的设置不能更改,除非重新创建索引。
相关推荐
阿昌喜欢吃黄桃7 天前
RocketMq事务消息原理
java·中间件·消息队列·rocketmq·mq
半夜修仙8 天前
延迟队列的介绍及常见问题
java·数据库·中间件·rabbitmq
手握风云-8 天前
一条消息的旅程:RabbitMQ 学习与实践(一)
中间件·rabbitmq
RH2312119 天前
2026.6.8Linux
java·数据库·中间件
理人综艺好会10 天前
双Token机制在实际项目中的应用与实践
中间件·token
番茄去哪了10 天前
神领物流面试题(一)
java·大数据·中间件
念何架构之路10 天前
消息中间件
中间件
都说名字长不会被发现10 天前
Spring Boot Starter 中间件账号密码加密方案设计与实现
java·spring boot·后端·中间件
瀚高PG实验室11 天前
java中间件无法连接数据库
java·数据库·中间件·瀚高数据库
之歆11 天前
Day11_Express 深入解析:从中间件到项目实战
中间件·express