大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Mapping 与字段类型
Mapping 定义 Index 中字段如何被索引与分析。选错类型会导致搜不到、聚合失败或磁盘暴涨——比 MySQL DDL 更「不可逆」,需提前规划。
学习目标
- 区分
text与keyword及使用场景 - 理解 dynamic mapping 的便利与风险
- 为
cf_track搜索场景设计合理 Mapping
核心内容
text vs keyword
| 类型 | 分词 | 典型用途 |
|---|---|---|
| text | 是(analyzer) | 标题、摘要、正文全文检索 |
| keyword | 否 | slug、枚举、精确过滤、排序、聚合 |
curl -X PUT "localhost:9200/tracks" -H "Content-Type: application/json" -d '
{
"mappings": {
"properties": {
"slug": { "type": "keyword" },
"title": { "type": "text", "fields": { "raw": { "type": "keyword" } } },
"summary": { "type": "text" },
"category": { "type": "keyword" },
"level": { "type": "keyword" },
"lessonCount": { "type": "integer" },
"updatedAt": { "type": "date" }
}
}
}'
title.raw 多字段:全文用 title,按标题字母序排序用 title.raw。
其他常用类型
integer/long/float:数值范围查询、metric 聚合date:ISO8601 或 epoch;配合 es-aggdate_histogramboolean:过滤 flagsnested/object:嵌套结构(慎用深层嵌套)
dynamic mapping 风险
未显式 Mapping 时 ES 自动推断:字符串 → text + keyword 双字段,可能不符合预期。
# 误把 slug 当 text 分词 → 搜 "spring-boot" 可能匹配不到完整 slug
curl -X POST "localhost:9200/tracks/_doc" -H "Content-Type: application/json" -d '
{ "slug": "spring-boot-essentials", "title": "Spring Boot" }'
最佳实践:实验 index 先 PUT Mapping,再 bulk 导入;生产变更需 reindex(es-scale)。
对照 MySQL schema
cf_track.slug → ES keyword;title/summary → text;category/level → keyword 过滤面。
MySQL 仍是权威:spring-boot-essentials JPA 实体变更后,通过 es-sync 更新 ES,而非反向以 ES 为准。
中文分词:生产常用 IK 插件;本 track 默认 standard analyzer,英文 track 名足够练习。
练习
- 为
tracks手写完整 Mapping,对照schema.sql的cf_track - 解释为何
slug必须用 keyword 而非 text - 试写入一条缺字段文档,观察 dynamic 行为
小结
text 搜全文,keyword 做精确与聚合;先 Mapping 后灌数。 下一课文档 CRUD 与 bulk。