← 返回题目列表

Elasticsearch 的 analyzer、tokenizer 和 token filter 有什么区别?

高频 中等 第 3 / 30 题 更新于 2026/07/29
Elasticsearch分词器AnalyzerTokenizer

简化版

analyzer 是完整分析链,通常由 character filter、tokenizer 和 token filter 组成。tokenizer 负责把文本切成 token,token filter 负责对 token 做小写、停用词、同义词、词干等处理;索引时和搜索时 analyzer 不一致,可能导致查不到或召回异常。

详细版

Elasticsearch 的全文检索不是直接拿原字符串匹配,而是先分析文本。典型链路是:character filter 先清洗原文,tokenizer 切词,token filter 再规范化 token。

"The Quick Foxes!"
-> tokenizer
-> ["The", "Quick", "Foxes"]
-> lowercase/stemmer
-> ["the", "quick", "fox"]

面试回答要强调:analyzer 是总装配,tokenizer 是切词器,token filter 是 token 后处理。text 字段会走 analyzer,keyword 字段通常保持整体值。中文、英文、日志、商品名的 analyzer 设计不同,要用 _analyze API 验证实际 token。

完整版教学

一、为什么搜索前要做文本分析

全文检索面对的是自然语言,不是简单等值匹配。用户搜 quick fox,文档里可能写 The Quick Foxes;如果按原字符串精确比较,就很难召回。

文本分析的目标是把“人类语言”转成“可检索 token”。大小写、标点、复数、同义词、中文切词都会影响召回和相关性。

原文: The Quick Foxes!
期望: quick / fox 这些词能被搜索命中

记忆钩子:Analyzer 是流水线,tokenizer 负责切开,token filter 负责打磨。

二、Analyzer 是完整流水线

一个 analyzer 通常包含 3 层。

组件输入输出例子
character filter原始字符串清洗后的字符串去 HTML、字符映射
tokenizer字符串token 列表standard、keyword、ngram
token filtertoken 列表新 token 列表lowercase、stop、synonym

流程可以画成:

raw text
  -> char_filter
  -> tokenizer
  -> token_filter
  -> indexed tokens

如果只记 tokenizer,就会漏掉很多线上问题。例如 HTML 标签没清洗、大小写没统一、同义词放错位置,都可能导致搜索体验异常。

三、Tokenizer 决定怎么切词

Tokenizer 是分析链里最核心的一步,它决定文本如何被切成 token。

常见 tokenizer:

tokenizer行为适合场景
standard按 Unicode 文本规则切分通用英文、混合文本
keyword整个输入当一个 token标签、枚举、编号
ngram按 N 个字符切片模糊匹配、部分匹配
edge_ngram从开头生成前缀搜索建议、前缀补全

比如 keyword tokenizer 处理 Beijing China 会得到 1 个 token;standard 可能得到 2 个 token。这个差异会直接决定查询能否命中。

四、Token filter 改变 token 的形态

Token filter 在切词之后工作,常见动作是小写化、去停用词、同义词扩展、词干还原。

["The", "Quick", "Foxes"]
lowercase -> ["the", "quick", "foxes"]
stop      -> ["quick", "foxes"]
stemmer   -> ["quick", "fox"]

顺序很重要。同义词、词干、大小写如果顺序不合理,生成 token 会不同。比如先做同义词还是先做词干,可能影响同义词规则能否匹配。

面试里可以补一句:不要凭想象判断分词结果,用 _analyze API 看真实 token。

五、索引 analyzer 和搜索 analyzer 可以不同

字段可以设置索引时 analyzer,也可以设置搜索时 analyzer。索引 analyzer 决定写入倒排索引的 token,搜索 analyzer 决定查询文本被拆成什么 token。

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

常见策略是索引时切得细一点,提高召回;搜索时切得粗一点,提高精度。但这不是固定公式,商品搜索、文章搜索、日志搜索的目标不同。

六、用 _analyze API 做验证

分析器配置必须测试。一个简单 _analyze 请求能让你看到最终 token。

POST /_analyze
{
  "analyzer": "standard",
  "text": "The Quick Foxes!"
}

如果返回 token 是 thequickfoxes,你就能判断停用词和词干有没有生效。线上搜索问题常常不是查询 DSL 错,而是 analyzer 产生的 token 与预期不同。

验证时至少测 3 类样本:正常词、边界词、业务特殊词。比如中文品牌名、英文缩写、带连字符型号、同义词词典里的词。

七、常见误区与追问

  • 误区:Analyzer 和 tokenizer 是一回事。 Analyzer 是完整流水线,tokenizer 只是其中负责切词的一环。
  • 误区:分词越细召回越好就一定越好。 分词太细会引入噪声,相关性下降,商品名尤其容易误召回。
  • 误区:索引 analyzer 和搜索 analyzer 必须一样。 可以不同,但要明确召回和精度取舍,并用样本验证。
  • 追问:为什么 keyword 字段不适合全文搜索? keyword 通常整体作为一个 token,更适合精确过滤、排序和聚合。
  • 追问:中文搜索为什么常要自定义 analyzer? 中文没有天然空格分隔,默认分析器很难满足业务词边界。
  • 追问:怎么排查搜不到?_analyze 看索引和查询 token,再看 mapping、字段类型和查询 DSL。

八、加强记忆

Elasticsearch 分词题记成“清洗、切词、打磨、验证”。Analyzer 是总流水线,character filter 清洗原文,tokenizer 切出 token,token filter 做小写、停用词、同义词等后处理。索引和搜索 analyzer 可能不同,但必须用 _analyze 验证真实 token;搜索查不到时,先别急着改 DSL,先看字段类型和分析结果。