4 分词器

4.1 分词器文件写法

elasticsearch-settings.json这个文件是 Elasticsearch 的 索引映射配置(本质是 JSON 格式),核心作用是 “告诉 Elasticsearch:我的索引里,字段该怎么存储、怎么分词”。

1.整体结构(3 层核心)

配置结构很简单:analysis 下分 analyzer(分词器)和 filter(过滤器),分词器里指定 “拆分工具(tokenizer)” 和 “加工工具(filter)”。
{
  "analysis": {          // 第1层:定义“分词相关配置”(所有分词器、过滤器都放这里)
    "analyzer": {        // 第2层:定义“分词器”(核心是“用什么拆分词+用什么过滤器处理词”)
      "自定义分词器名": { // 第3层:具体分词器配置(比如 file_name_analyzer)
        "type": "custom",// 分词器类型:custom=自定义(不是ES内置的)
        "tokenizer": "ik_max_word", // 核心:用什么“分词器”拆分词(ik_max_word=IK细粒度分词)
        "filter": ["lowercase", "word_delimiter"] // 辅助:拆分后对词做什么处理(转小写、拆分特殊字符)
      }
    },
    "filter": {          // 第2层:定义“分词过滤器”(可复用的处理逻辑,比如转小写、拆分特殊字符)
      "自定义过滤器名": { // 第3层:具体过滤器配置(比如 hyphenation_filter)
        "type": "word_delimiter", // 过滤器类型:word_delimiter=拆分特殊字符连接的词
        "split_on_numerics": true, // 是否拆分数字(比如 v1.0 → v、1、0)
        "split_on_case_change": true, // 是否按大小写拆分(比如 FileShare → File、Share)
        "preserve_original": true // 是否保留原始词(比如 project-management 拆分后,仍保留原始词)
      }
    }
  }
}

2.关键部分说明

  • analyzer:分词器
相当于 “拆分词的工具 + 处理词的工具组合”。比如 file_name_analyzer 是 “用 IK 细粒度拆分词,再转小写 + 拆分特殊字符”。
  • filter:分词过滤器
相当于 “词的加工工具”,可复用。比如 hyphenation_filter 是 “专门拆分特殊字符连接的词,同时保留原始词”。
  • 索引分词器 vs 搜索分词器
  • 索引分词器(比如 file_name_analyzer):存数据时用,尽可能细粒度拆分,让后续搜索能匹配到更多结果;
  • 搜索分词器(比如 file_name_search_analyzer):查数据时用,粗粒度拆分,优先匹配完整词,提升搜索精度和效率。

4.2 索引分词器 vs 搜索分词器

1.核心定位:二者是搜索引擎中分工明确的 “拆分规则”,索引分词器用于建立索引(存数据),搜索分词器用于查询索引(查数据),协同支撑搜索流程。

2.索引分词器核心逻辑:

  • 核心策略:按业务需求拆分文本,核心倾向是最大化拆分粒度(如 “苹果手机 iPhone15” 拆为 “苹果”“手机”“iPhone”“15”)。
  • 核心目的:生成更多丰富词项存入倒排索引,确保后续搜索时 “不遗漏潜在相关结果”,提升召回率。

3.搜索分词器核心逻辑:

  • 核心策略:按业务需求拆分查询词,无固定粒度(可粗可细,如 “苹果手机” 可拆为 “苹果手机” 单个词,也可拆为 “苹果”“手机”)。
  • 核心目的:生成符合查询意图的词项,去倒排索引中匹配完全一致的词项,核心是提升搜索精确率、相关性和查询效率。

4.协同流程:

  • 索引阶段:文档文本 → 索引分词器拆分 → 生成词项 → 构建倒排索引(词项与对应文档 ID 的映射)。
  • 搜索阶段:用户查询词 → 搜索分词器拆分 → 生成查询词项 → 匹配倒排索引中的词项 → 返回对应文档。

5.关键依赖:底层依赖倒排索引数据结构,分词器的拆分规则直接决定索引的词项构成和查询的匹配逻辑。

6.通用使用原则:

  • 灵活匹配粒度:索引与搜索分词器的粒度无固定绑定,需按业务场景设计(如模糊搜索可 “索引细、搜索细”,精准搜索可 “索引细、搜索粗”)。
  • 默认通用场景:多数情况下使用相同分词器处理索引和搜索,确保拆分规则一致,避免匹配偏差。
  • 特殊场景适配:需精准匹配(如 SKU、订单号)时,可让搜索分词器粒度粗于索引分词器;需模糊匹配(如内容检索)时,可让二者粒度保持一致或搜索分词器更细。

4.3 索引分词器与搜索分词器三种配置组合对比

索引分词器与搜索分词器三种配置组合一共有三种,分别是:索引和搜索分词器都一样(且是细粒度)、索引细但搜索粗和索引粗但搜索细。
配置组合
核心拆分逻辑
召回率
精准度
适用场景
实例(文档:“苹果手机 iPhone 15”)
索引细、搜索细
(通用默认)
索引:细粒度拆分(拆为 “苹果”“手机”“iPhone”“15”)
搜索:同索引的细粒度拆分规则
通用模糊搜索场景(内容检索、电商商品模糊查询、资讯搜索)
搜索 “苹果手机”→拆为 “苹果”“手机”→均匹配索引词项→成功返回结果;
搜索 “15”→拆为 “15”→匹配索引→成功返回
索引细、搜索粗
(精准匹配)
索引:细粒度拆分(拆为 “苹果”“手机”“iPhone”“15”)
搜索:粗粒度拆分(或不分词,如 “苹果手机” 拆为单个词)
精准匹配场景(SKU 搜索、产品型号精准查询、订单号 / 编号搜索)
搜索 “苹果手机”→拆为 “苹果手机”→索引无该词项→匹配失败;
搜索 “iPhone 15”→按空格拆为 “iPhone”“15”→均匹配索引→成功返回
索引粗、搜索细
(极少使用)
索引:粗粒度拆分(拆为 “苹果手机 iPhone15” 单个词项)
搜索:细粒度拆分(如 “苹果手机” 拆为 “苹果”“手机”)
极低
极端严格匹配场景(保密文档编号、唯一标识强制完整输入),实际几乎不用
搜索 “苹果”→拆为 “苹果”→索引无该词项→匹配失败;
搜索 “苹果手机 iPhone15”→拆为 “苹果”“手机”“iPhone”“15”→均无匹配→失败(仅完整输入原文本才可能匹配)
核心总结
  1. 索引是 “匹配词项基础池”,细粒度索引能扩大词项范围,为召回率提供保障。
  2. 搜索是 “筛选规则”,粒度选择需适配索引词项:索引细时搜索可细可粗(按需切换模糊 / 精准),索引粗时搜索细会导致词项无法匹配。
  3. 实际应用中优先选择前两种配置,第三种因召回率极低,仅极端场景可能用到(且多被 “索引粗、搜索粗” 替代)。
具体解释如下(仅看上面的总结就足够了,如果上面看不懂在看下面的):
示例文档:id: 1, content: "苹果手机 iPhone 15"

4.3.1 索引分词器 = 搜索分词器 = 细粒度(例如:Standard Analyzer)

这是最常见的默认配置。索引和搜索都使用相同的、细粒度的分词器。

1.索引阶段 (Indexing)

  • 分词器:标准分词器 (细粒度)
  • 处理过程:"苹果手机 iPhone 15" -> ["苹果", "手机", "iphone", "15"]
  • 倒排索引中存储的词项:"苹果", "手机", "iphone", "15"

2.搜索阶段 (Searching)

查询词会经过同一个标准分词器处理。
我们来看三个不同的查询词:
  • 查询 A:"苹果手机"
  • 分词处理:"苹果手机" -> ["苹果", "手机"]
  • 搜索行为:ES 会去倒排索引中查找 ** 包含 "苹果" 或包含 "手机"** 的文档。
  • 匹配结果:文档 1 的索引中既有 "苹果" 也有 "手机",成功匹配。
  • 结果评分:相关性得分会很高,因为两个词都匹配上了。
  • 查询 B:"苹果"
    • 分词处理:"苹果" -> ["苹果"]
    • 搜索行为:ES 查找包含 "苹果" 的文档。
    • 匹配结果:文档 1 包含 "苹果",成功匹配。
    • 结果评分:相关性得分一般。
  • 查询 C:"iPhone 15"
    • 分词处理:"iPhone 15" -> ["iphone", "15"]
    • 搜索行为:ES 查找包含 "iphone" 或 "15" 的文档。
    • 匹配结果:文档 1 两个词都包含,成功匹配。
    • 结果评分:相关性得分很高。
这种配置下,只要查询词的任何一个分词能在文档的分词中找到,就能匹配。这极大地提高了召回率,用户可以用各种关键词、同义词、部分词组来进行模糊搜索,都有机会找到相关结果。但缺点是可能返回不那么精确的结果。例如,如果还有一个文档是 "苹果电脑 MacBook Pro",那么查询 "苹果" 也会把这个文档返回。

4.3.2 索引分词器 = 细粒度,搜索分词器 = 粗粒度

这是上面代码中使用的策略,用于特定的精确匹配场景。

1.索引阶段 (Indexing)

  • 分词器:标准分词器 (细粒度)
  • 处理过程:"苹果手机 iPhone 15" -> ["苹果", "手机", "iphone", "15"]
  • 倒排索引中存储的词项:"苹果", "手机", "iphone", "15"
  1. 搜索阶段 (Searching)
我们假设搜索分词器是一个只按空格分词的分词器 (Whitespace Analyzer),这是一种粗粒度的策略。
同样用三个查询词来测试:
  • 查询 A:"苹果手机"
    • 分词处理:"苹果手机" 中没有空格,所以被当作一个完整的词 -> ["苹果手机"]
    • 搜索行为:ES 拿着 "苹果手机" 这个完整的词项去倒排索引中查找完全相等的词。
    • 匹配结果:倒排索引里只有 "苹果"、"手机" 等,没有 "苹果手机" 这个词。匹配失败,无结果返回。
  • 查询 B:"苹果"
    • 分词处理:"苹果" -> ["苹果"]
    • 搜索行为:ES 拿着 "苹果" 去索引中查找。
    • 匹配结果:索引里有 "苹果" 这个独立的词项。成功匹配。
  • 查询 C:"iPhone 15"
    • 分词处理:"iPhone 15" 中有一个空格,所以被拆分为 -> ["iPhone", "15"]
    • 搜索行为:ES 拿着 "iPhone" 和 "15" 这两个词项去索引中查找。
    • 匹配结果:索引里存在 "iphone" (假设分词器大小写不敏感) 和 "15"。成功匹配。
这种配置下,搜索的匹配条件变得非常苛刻。它要求查询词的分词结果必须与索引中的某个词项完全一样。
  • 查询 "苹果手机" 失败,因为它被当作一个词,而索引里没有这个词。
  • 查询 "苹果" 成功,因为它本身就是一个词。
  • 查询 "iPhone 15" 成功,因为空格把它拆成了两个词,而这两个词在索引里都存在。
这种策略极大地提高了搜索的精确率,可以有效过滤掉那些只包含部分关键词的不相关文档。但代价是召回率降低,用户必须使用非常精确的查询词才能找到结果。

4.3.3 索引分词器 = 粗粒度,搜索分词器 = 细粒度

1.索引阶段(粗粒度分词器,如关键词分词器):

文本 “苹果手机 iPhone15” → 不分词,仅存["苹果手机iPhone15"]一个词项。

2.搜索阶段(细粒度分词器,如标准分词器):

  • 查询 “苹果”:拆成["苹果"] → 索引中无该词项 → 匹配失败。
  • 查询 “苹果手机”:拆成["苹果", "手机"] → 索引中无这两个词项 → 匹配失败。
  • 查询 “苹果手机 iPhone15”:拆成["苹果", "手机", "iphone", "15"] → 索引中无任何一个细词项 → 匹配失败(除非搜索时用 “完全匹配” 语法,但失去了分词意义)。
索引粗、搜索细几乎无实用场景。搜索词拆得细,索引词项粗,会导致难以命中,召回率极低。
  • 索引的核心作用是 “尽可能收录潜在匹配词”,粗粒度索引直接限制了可匹配的词项范围,相当于 “基础池太小”。
  • 搜索的核心作用是 “精准筛选”,细粒度搜索是在 “基础池” 里找细分词,而 “基础池” 本身没有细分词,自然无从筛选。
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐