3.1 映射:文档进站前的登记表 本节摘要:映射(mapping)声明每个字段的类型与索引方式,是文档进站前的登记表。本节从动态映射的风险讲到显式映射的完整写法,覆盖 text 与 keyword 的双形态套路、数值与日期的选型、常用参数的调档,最后解释为什么改类型只能重建索引。映射是旅程中"一次决定、长期生效"的环节,值得最谨慎的一次投入。 登记表怎么读 第 2 章写入 doc-1001 时,字段类型是引擎猜出来的:title 猜成 text,priority 猜成整数。猜,在学习期省事,在生产期是隐患。真实数据里这种事故屡见不鲜:工单号 WC-2026-08-20-001 看起来像日期,被推断成日期类型后解析失败;
本节摘要:映射(mapping)声明每个字段的类型与索引方式,是文档进站前的登记表。本节从动态映射的风险讲到显式映射的完整写法,覆盖 text 与 keyword 的双形态套路、数值与日期的选型、常用参数的调档,最后解释为什么改类型只能重建索引。映射是旅程中"一次决定、长期生效"的环节,值得最谨慎的一次投入。
第 2 章写入 doc-1001 时,字段类型是引擎猜出来的:title 猜成 text,priority 猜成整数。猜,在学习期省事,在生产期是隐患。真实数据里这种事故屡见不鲜:工单号 WC-2026-08-20-001 看起来像日期,被推断成日期类型后解析失败;状态字段的中文值被推成 text,导致聚合时拿到的是切碎的词条而非完整状态。所以第一纪律是:生产索引关闭动态推断,映射显式声明。
一份显式映射长这样:
PUT tickets_v2 { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "dynamic": "strict", "properties": { "ticket_id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "standard", "fields": { "raw": { "type": "keyword" } } }, "status": { "type": "keyword" }, "priority": { "type": "integer" }, "created_at": { "type": "date", "format": "epoch_millis||strict_date_optional_time" }, "reply": { "type": "text", "index": false }, "views": { "type": "long", "doc_values": true } } } }
逐行读这份登记表:ticket_id 用 keyword——它是精确标识,永远整存整取;title 用 text 做全文检索,同时挂一个 keyword 子字段 raw 供排序聚合;status 是枚举,keyword 让"待处理"保持完整形态;created_at 接受毫秒时间戳或标准日期串两种输入;reply 设 index 为 false——只展示不检索,省下倒排开销;views 的 doc_values 默认开启,为排序与聚合提供列式存储。dynamic 设为 strict 后,写入映射外的新字段直接报错,脏数据在门口就被拦下。
| 类型 | 建的结构 | 买到了什么 | 典型字段 |
|---|---|---|---|
| text | 分词后的倒排表 | 全文检索与打分 | 标题、内容、评论 |
| keyword | 整串单词条倒排表 | 精确匹配、聚合、排序 | 状态、标签、单号 |
| integer 或 long | 数值型字典 | 范围过滤、聚合 | 优先级、浏览量 |
| date | 统一为时间戳 | 范围过滤、日期直方图 | 创建时间 |
| boolean | 四值词典 | 是非过滤 | 是否加急 |
| geo_point | 网格编码 | 距离与范围检索(第 7 章) | 服务网点坐标 |
最容易迷惑的是 text 与 keyword 的分野,一张决策路径把它们钉死:

工单的 title 就是折中路线的受益者:用户按"退款"模糊搜走 text 形态;报表按完整标题去重统计走 raw 子字段。一份字段,两种形态,各取所需。
映射里最常用的三根旋钮值得单独记住:
{ "说明": "三根旋钮的语义", "index": "false 时字段不建倒排 搜不到但_source里还在 省空间", "doc_values": "false 时字段失去聚合排序能力 换取磁盘 搜索型字段可关", "null_value": "给空值一个替身 REPLACE 之类 空值也能被term过滤命中" }
旋钮背后是空间与能力的交换:index 关掉省倒排、doc_values 关掉省列存,都对应一份功能让渡。没有免费午餐,只有明确取舍。
映射为什么如此"专制"?因为字段类型决定了物理结构:text 的倒排表按词条组织,keyword 的倒排表只有一个整串词条,数值走 BKD 树,日期被折算成统一时间戳。类型一变,底层结构全变,而已写入的数据不可能就地重组。引擎的态度很干脆:允许加新字段,禁止改老字段的类型。想改怎么办?标准流程是四步——建新映射的新索引、把数据从旧索引导过去(用重建索引接口或自己写的搬运程序)、别名切到新索引、删旧索引。这套流程在 3.3 会完整演练一次,它是"主分片数不可改"的同款解法。
⚠️ 常见坑:dynamic 设为 strict 后,业务新增字段会直接被拒之门外,写入报错映射异常。要么走严格的变更流程,要么设为 false(新字段只进 _source 不建索引),别图省事设回 true——那等于把登记表重新交给运气。
| 考核点 | 达标标准 |
|---|---|
| 类型选型 | 对给定字段清单写出正确类型并逐条说明理由 |
| 双形态套路 | 写出 text 挂 keyword 子字段的映射,说明两种形态各自服务谁 |
| 三根旋钮 | 说出 index、doc_values、null_value 各自交换了什么 |
| 动态三档 | 区分动态映射 true、false、strict 三档的行为与风险 |
| 重建流程 | 背出改类型的四步标准流程与每步的校验点 |
登记表填完,文档被推向真正的手术台:分析器如何把"用户申请退款"切成词条,下一节放到显微镜下看。