2、搜索索引映射基础:索引映射(Mapping)的定义、字段类型与分词器的作用

2.1 索引映射(Mapping)的定义

在分布式搜索引擎(如 Elasticsearch、OpenSearch)中,索引映射(Mapping) 是定义索引中字段的名称、数据类型以及索引方式的核心结构。它类似于关系型数据库中的 Schema(表结构),但更侧重于全文检索与倒排索引的构建规则。

映射决定了文档在写入索引时,每个字段如何被解析、存储和检索。没有正确的映射,搜索引擎无法理解字段是应该做精确匹配、范围查询还是全文分词搜索。

核心作用:映射是搜索引擎的“数据说明书”,它告诉引擎:“这个字段是数字,那个字段是文本,而这个文本字段需要用中文分词器拆成单词。”

2.2 字段类型(Field Types)

字段类型决定了字段的存储方式和查询行为。以下是搜索引擎中最常用的字段类型分类:

类别 字段类型 典型用途 索引行为
文本类型 text、keyword 全文搜索(text)、精确匹配/聚合(keyword) text 会经过分词器处理;keyword 保持原值
数值类型 integer、long、float、double 范围查询、排序、聚合计算 不进行分词,直接索引数值
日期类型 date 时间范围过滤、按时间排序 支持多种日期格式,内部转为时间戳
布尔类型 boolean 状态标记(是/否、启用/禁用) 索引为 true 或 false
对象/嵌套 object、nested JSON 对象、数组中的独立子文档 nested 保持数组内对象的独立性
地理类型 geo_point、geo_shape 地理位置搜索、距离排序 索引经纬度或几何形状
设计建议:在服务边界设计中,keyword 类型常用于“枚举值”或“业务主键”字段,而 text 类型用于“标题”、“描述”等需要分词检索的字段。错误的类型选择会导致查询性能下降或结果不准确。

2.3 分词器(Analyzer)的作用

分词器 是搜索引擎处理文本字段的核心组件。它将一段连续的文本拆分成多个词项(Token),并可能进行归一化处理(如转小写、去除停用词、提取词干)。

一个完整的分词器由以下三部分顺序组成:

  1. 字符过滤器(Character Filters): 在分词前对原始文本进行预处理,如去除 HTML 标签、替换特殊字符。
  2. 分词器(Tokenizer): 将文本按规则切分成词项。例如,standard 分词器按空格和标点切分;ik_smart 按中文语义切分。
  3. 词项过滤器(Token Filters): 对切分后的词项进行二次处理,如转小写、去除停用词(“的”、“是”)、添加同义词。
常见误区:很多开发者认为“只要字段类型是 text 就能搜到中文”。实际上,如果未配置中文分词器(如 IK、jieba),默认的 standard 分词器会将中文按单个汉字切分,导致“搜索引擎”被拆成“搜”、“索”、“引”、“擎”,无法匹配“搜索引擎”这个完整词组。

2.4 映射、字段类型与分词器的协同关系

下面的 SVG 图展示了文档写入索引时,映射如何驱动字段类型和分词器协同工作:

映射、字段类型与分词器协同流程 映射驱动下的字段处理流程 输入文档(JSON) 索引映射(Mapping) 字段类型定义 + 分词器配置 字段类型判断 text 类型 经过分词器 → 倒排索引 keyword 类型 不经过分词器 → 精确索引 可分词搜索、高亮 精确匹配、聚合、排序

2.5 映射定义示例

以下是一个典型的索引映射定义,展示了字段类型与分词器的配置方式:

PUT /product_index
{
  "mappings": {
    "properties": {
      "product_id": {
        "type": "keyword"          // 精确匹配,用于聚合和过滤
      },
      "title": {
        "type": "text",
        "analyzer": "ik_max_word", // 中文最大粒度分词
        "fields": {
          "keyword": {             // 多字段:同时支持精确匹配
            "type": "keyword"
          }
        }
      },
      "description": {
        "type": "text",
        "analyzer": "ik_smart"     // 中文智能分词,粒度较粗
      },
      "price": {
        "type": "double"           // 数值类型,支持范围查询
      },
      "created_at": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "tags": {
        "type": "keyword"          // 标签数组,每个标签精确匹配
      }
    }
  }
}
关键设计点:上述映射中 title 字段使用了 多字段(multi-fields) 特性。它既保留了 text 类型用于全文搜索,又通过 title.keyword 子字段支持精确匹配和聚合。这种设计在服务边界中非常实用,可以避免后期因需求变更而重建索引。

2.6 分词器对比与选择

不同的分词器适用于不同的语言和场景。下表对比了搜索引擎中常见的分词器:

分词器名称 适用语言 切分粒度 典型场景
standard 英文为主 按空格和标点切分 默认分词器,英文文档
ik_smart 中文 粗粒度(最简切分) 搜索精度要求高,减少噪音
ik_max_word 中文 细粒度(最大切分) 召回率要求高,需要更多匹配
whitespace 通用 仅按空格切分 保留原始词组,不做归一化
ngram 通用 按字符滑动窗口切分 模糊搜索、自动补全
服务边界视角:在微服务架构中,每个服务可能拥有独立的索引。如果“商品服务”使用 ik_max_word 而“搜索服务”使用 ik_smart,会导致同一字段在不同索引中的分词结果不一致,进而影响跨服务搜索的准确性。因此,分词器选择应在服务边界内统一约定,并作为映射版本管理的一部分。

2.7 映射的不可变性约束

映射一旦创建,部分字段类型是不可修改的。这是搜索引擎底层倒排索引结构决定的。下图展示了映射变更的约束边界:

映射字段变更约束 映射字段变更约束矩阵 ✅ 可动态变更 • 新增字段(动态映射) • 修改分词器参数 • 添加多字段(multi-fields) • 修改字段的 ignore_above • 修改 null_value ❌ 不可变更(需重建索引) • 修改字段类型(如 text → keyword) • 修改分词器类型(如 standard → ik) • 删除已有字段 • 修改 index 属性(true → false) • 修改 doc_values 设置
版本管理启示:由于映射的不可变性约束,任何涉及字段类型或分词器变更的需求,都必须通过索引重建(Reindex)或别名切换(Alias Swap)来实现。这正是后续章节“映射版本管理”的核心出发点——通过版本号管理映射的迭代,避免生产环境直接修改映射导致服务中断。