Elasticsearch(ES)的分词是全文检索的核心环节,其本质是将 原始文本(如一句话、一段日志)拆分成若干个有意义的“词(Term)”,这些词会被存入倒排索引,供后续查询时快速匹配。分词的质量直接影响检索的准确性(能否精准匹配)和召回率(能否找到所有相关结果)。

一、分词的核心作用

在ES中,分词发生在两个阶段:

  • 索引时:当文档写入ES时,会对text类型的字段进行分词,将拆分后的Term存入倒排索引(记录Term与文档的对应关系)。
  • 搜索时:用户输入查询文本时,ES会对查询文本执行相同的分词逻辑,得到Term后,去倒排索引中匹配包含这些Term的文档。

关键原则:索引和搜索时的分词逻辑必须一致(或兼容),否则会导致“索引的Term”与“搜索的Term”不匹配,查询不到结果。例如:索引时将“Hello”拆分为小写“hello”,但搜索时未小写处理,就会匹配失败。

二、分词器(Analyzer):分词的“执行单元”

ES的分词由分词器(Analyzer) 完成,一个分词器是三个组件的组合,按顺序执行:

原始文本 → 字符过滤器(Character Filter) → 分词器(Tokenizer) → 词元过滤器(Token Filter) → 最终Term  
1. 字符过滤器(Character Filter):预处理原始文本

作用:在文本被拆分前,对原始字符串进行清洗或转换(如去除无用字符、替换特殊符号)。

  • 可配置多个,按顺序执行。
  • 常见类型:
    • html_strip:去除HTML标签(如将<p>hello</p>转换为hello)。
    • mapping:替换指定字符(如将:-)替换为happy)。
    • pattern_replace:用正则表达式替换(如将数字替换为NUMBER)。
2. 分词器(Tokenizer):拆分文本为词元(Token)

作用:将预处理后的文本按规则拆分成若干个“词元(Token)”(尚未最终存入索引的临时词),是分词的核心步骤。

  • 一个分词器必须且只能有一个Tokenizer。
  • 拆分规则由Tokenizer的类型决定,例如:
    • Standard Tokenizer(默认):按Unicode文本分割规则拆分(空格、标点、符号等视为分隔符),并去除大部分标点。
      例:"Hello, world! 123" → 拆分为 ["Hello", "world", "123"]
    • Whitespace Tokenizer:仅按空格拆分,保留标点。
      例:"Hello, world! 123" → 拆分为 ["Hello,", "world!", "123"]
    • Letter Tokenizer:仅按非字母字符拆分(只保留字母组成的词)。
      例:"Hello, world! 123" → 拆分为 ["Hello", "world"](数字和标点被当作分隔符)。
    • 中文分词器(如IK Tokenizer):针对中文无空格的特点,按语义拆分(基于词典和规则)。
      例:"我爱北京天安门" → 拆分为 ["我", "爱", "北京", "天安门"]
3. 词元过滤器(Token Filter):优化词元

作用:对Tokenizer输出的词元进行二次处理(如过滤、转换、增删),最终生成存入索引的Term。

  • 可配置多个,按顺序执行。
  • 常见类型:
    • lowercase:将词元转为小写(解决大小写不敏感问题)。
      例:["Hello", "World"] → 转为 ["hello", "world"]
    • stop:去除停用词(无实际意义的词,如“的”“a”“the”)。
      例:["我", "的", "北京"] → 过滤后 ["我", "北京"]
    • synonym:替换同义词(提升召回率)。
      例:配置“西红柿→番茄”,则 ["西红柿"] → 转为 ["番茄", "西红柿"](同时保留原词和同义词)。
    • stemmer:词干提取(将动词变体转为原型,如“running”→“run”)。

三、内置分词器与自定义分词器

ES提供了多种内置分词器(已组合好Character Filter、Tokenizer、Token Filter),满足常见场景:

  • standard(默认):Standard Tokenizer + lowercase + stop(默认去除英文停用词)。
  • simpleLetter Tokenizer + lowercase(只保留字母并小写)。
  • whitespace:仅Whitespace Tokenizer(按空格拆分,不做其他处理)。
  • keyword:特殊分词器,不拆分文本(将整个文本作为一个Term,类似keyword类型的字段)。

如果内置分词器不满足需求(如中文分词、自定义规则),可自定义分词器,例如:

// 定义一个中文分词器(使用IK分词+小写转换+过滤停用词)  
"settings": {  
  "analysis": {  
    "analyzer": {  
      "my_ik_analyzer": {  // 自定义分词器名称  
        "type": "custom",  
        "char_filter": [],  // 无字符过滤  
        "tokenizer": "ik_max_word",  // IK分词器(细粒度拆分)  
        "filter": ["lowercase", "stop"]  // 转小写+过滤停用词  
      }  
    }  
  }  
}  

四、中文分词的特殊性

英文等语言天然以空格分隔单词,分词规则简单;但中文无空格,且存在“一词多义”“歧义”(如“南京市长江大桥”可拆分为“南京市/长江大桥”或“南京/市长/江大桥”),因此需要专门的中文分词器:

  • IK分词器:最常用的中文分词器,支持“ik_smart”(粗粒度拆分,适合精准匹配)和“ik_max_word”(细粒度拆分,适合召回率优先)。
  • Jieba分词器:基于Python的分词库,ES可通过插件集成,支持自定义词典和新词发现。
  • THULAC:清华大学开源的分词工具,精度较高,但性能略低。

中文分词的核心是词典+规则+模型

  • 词典:内置常用词库(如“北京”“天安门”),确保已知词正确拆分。
  • 规则:处理未登录词(词典中没有的词,如网络新词“内卷”)。
  • 模型:部分分词器结合机器学习模型(如BERT),解决歧义问题(如通过上下文判断拆分方式)。

五、关键注意事项

  1. 字段类型与分词

    • text类型:会被分词,用于全文检索。
    • keyword类型:不分词(整个字段作为一个Term),用于精确匹配、排序、聚合。
      (建议对text字段同时设置keyword子字段,如name.keyword,兼顾检索和聚合)。
  2. 索引与搜索分词器一致性

    • 索引时用analyzer(默认与字段配置一致),搜索时用search_analyzer(默认与analyzer相同)。
    • 若需特殊处理(如搜索时用更粗粒度的分词),可单独配置search_analyzer
  3. 分词效果测试
    可通过ES的_analyzeAPI测试分词结果,验证是否符合预期:

    GET /_analyze  
    {  
      "analyzer": "ik_max_word",  
      "text": "我爱北京天安门"  
    }  
    

总结

ES的分词是“文本预处理→拆分→优化”的流水线过程,核心是通过分词器将文本转化为可检索的Term。合理配置分词器(尤其是中文场景)是提升检索效果的关键——既需要准确拆分有意义的词,又要通过过滤、同义词等处理平衡“精准度”和“召回率”。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐