面试知识库
进阶

分词器与Analyzer#

一句话答案#

ES Analyzer 由「字符过滤器 → 分词器(Tokenizer)→ Token 过滤器」三部分组成,中文常用 IK 分词器(ik_max_word 细粒度建索引,ik_smart 粗粒度查询),分词效果直接决定搜索召回率。

核心要点

Analyzer 处理流程#

原始文本: "Elasticsearch是一个分布式搜索引擎"

Character Filters (字符过滤): 去HTML标签、特殊字符替换
    ↓ "Elasticsearch是一个分布式搜索引擎"
Tokenizer (分词): 按规则切分为词项
    ↓ ["elasticsearch", "是", "一个", "分布式", "搜索", "引擎"]
Token Filters (词项过滤): 小写、停用词、同义词
    ↓ ["elasticsearch", "分布式", "搜索", "引擎"]  (去掉停用词"是""一个")
plaintext

内置分词器#

分词器适用效果
standard英文(默认)按空格+标点切分,小写
simple英文按非字母字符切分
whitespace日志/代码仅按空格切分
keyword精确匹配不分词,整体作为一个 Token
ik_max_word中文建索引最细粒度切分(召回率高)
ik_smart中文查询最粗粒度切分(精确度高)

IK 分词器对比#

输入: "中华人民共和国"

ik_max_word: ["中华人民共和国", "中华人民", "中华", "华人", "人民共和国", "人民", "共和国", "共和", "国"]
ik_smart:    ["中华人民共和国"]

建索引用 ik_max_word → 保证各种查询都能匹配
查询用 ik_smart → 避免过度拆分导致无关结果
plaintext

自定义 Analyzer#

Mapping 中指定分词器#

{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "brand": {
        "type": "keyword"
      }
    }
  }
}
json

分词调试#

POST /_analyze
{
  "analyzer": "ik_smart",
  "text": "Java并发编程实战"
}
// 结果: ["java", "并发", "编程", "实战"]
plaintext
面试回答(2分钟版)

ES 的 Analyzer 分三步:Character Filter 清洗原始文本(如去 HTML 标签),Tokenizer 按规则切分成词项,Token Filter 做后处理(小写化、去停用词、同义词扩展)。中文分词用 IK 插件,有两种模式:ik_max_word 最细粒度切分用于建索引,保证召回率;ik_smart 最粗粒度切分用于查询,保证精确度。Mapping 里可以分别指定建索引的 analyzer 和搜索时的 search_analyzer。实践中还会配置同义词过滤器(比如”手机”和”移动电话”互通),停用词过滤器去掉”的""了”等无意义词。分词效果直接影响搜索质量,可以用 _analyze API 调试验证分词结果。

追问与易错

追问方向:

  • “ik_max_word 和 ik_smart 怎么配合?”→ 索引用 max_word 保证召回,查询用 smart 保证精确
  • “怎么支持拼音搜索?”→ pinyin 分词器插件,建索引时同时存储拼音 Token
  • “分词器能动态更新吗?”→ IK 支持热更新词典(远程词典 URL),不需要重启
  • “keyword 和 text 类型区别?”→ keyword 不分词走精确匹配,text 分词走全文搜索

易错点:

  • ❌ “默认分词器能处理中文”——standard 对中文是逐字切分,效果极差
  • ❌ “改了 Analyzer 立即生效”——已建好的索引需要 reindex 才能应用新分词
  • ❌ “同义词放 search_analyzer 就行”——建索引时也要扩展同义词,否则只搜得到原词