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),并可能进行归一化处理(如转小写、去除停用词、提取词干)。
一个完整的分词器由以下三部分顺序组成:
- 字符过滤器(Character Filters): 在分词前对原始文本进行预处理,如去除 HTML 标签、替换特殊字符。
- 分词器(Tokenizer): 将文本按规则切分成词项。例如,
standard分词器按空格和标点切分;ik_smart按中文语义切分。 - 词项过滤器(Token Filters): 对切分后的词项进行二次处理,如转小写、去除停用词(“的”、“是”)、添加同义词。
常见误区:很多开发者认为“只要字段类型是
text 就能搜到中文”。实际上,如果未配置中文分词器(如 IK、jieba),默认的 standard 分词器会将中文按单个汉字切分,导致“搜索引擎”被拆成“搜”、“索”、“引”、“擎”,无法匹配“搜索引擎”这个完整词组。
2.4 映射、字段类型与分词器的协同关系
下面的 SVG 图展示了文档写入索引时,映射如何驱动字段类型和分词器协同工作:
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 映射的不可变性约束
映射一旦创建,部分字段类型是不可修改的。这是搜索引擎底层倒排索引结构决定的。下图展示了映射变更的约束边界:
版本管理启示:由于映射的不可变性约束,任何涉及字段类型或分词器变更的需求,都必须通过索引重建(Reindex)或别名切换(Alias Swap)来实现。这正是后续章节“映射版本管理”的核心出发点——通过版本号管理映射的迭代,避免生产环境直接修改映射导致服务中断。