在大数据和搜索技术的世界里,Elasticsearch (ES) 无疑是那颗最闪亮的星。但很多初学者在刚接触 ES 时,往往会被"索引(Index)"、"映射(Mapping)"、"分片(Shard)"等概念搞得晕头转向。
如果把 Elasticsearch 比作一个超级物流中心 ,那么数据就是货物,搜索就是物流调配。而今天我们要聊的索引 和映射 ,就是这个物流中心的仓库架构 和智能管理系统。
只有懂了这两个核心概念,你才能真正驾驭 ES,把它从一个简单的"存数据的地方"变成一个能理解数据、极速响应的"智能仓库"。
一、 索引(Index):不仅仅是"目录"
在传统数据库(如 MySQL)中,我们提到"索引",通常指的是为了加速查询而给某一列加的 B+ 树数据结构。
但在 Elasticsearch 中,Index 是一个完全不同的概念。
1. 仓库的比喻
想象一下,你要存一批书:
- MySQL 的做法:把书扔进一个大房间(表),然后在门口贴一张小纸条(索引),告诉你哪本书在第几排。
- Elasticsearch 的做法 :直接给这批书盖一个独立的仓库。这个仓库有自己的安保、自己的货架布局、自己的管理人员。
在 ES 中,Index 是一类文档的集合 (类似于数据库中的 Table),但它更是一个物理上的容器。它由多个分片(Shards)组成,分布在不同的服务器上,共同构成了这个高可用的"仓库"。
2. 倒排索引:仓库的"黑科技"
为什么 ES 搜索这么快?因为它用的不是传统的"正向索引"(通过 ID 找内容),而是倒排索引(Inverted Index)。
- 正向索引:文档 ID -> 文档内容(像书的正文,从头读到尾)。
- 倒排索引:关键词 -> 包含该词的文档 ID 列表(像书后面的"名词索引")。
当你搜索"智能仓库"时,ES 不需要扫描所有文档,而是直接去"倒排索引"里查"智能"和"仓库"这两个词分别出现在哪些文档里,然后取交集。这就是毫秒级搜索的秘密。
二、 映射(Mapping):仓库的"智能管理规则"
有了仓库(Index),你把货物(JSON 文档)扔进去就完事了吗?不行!如果不告诉仓库管理员货物的属性,可能会出大乱子。
Mapping 就是定义这个仓库规则的说明书。 它告诉 ES:
- 这个字段是数字还是字符串?
- 这个字符串需要被切分(分词)还是当作一个整体?
- 这个字段是否需要被搜索?是否需要存储?
1. 核心概念:Text vs Keyword
这是 Mapping 中最重要、也最容易搞错的知识点。
-
Text 类型(分词):
- 场景:文章内容、商品描述、日志信息。
- 比喻 :把一句话切成一个个词。比如"Elasticsearch 索引与映射"会被切成
[elasticsearch, 索引, 映射]。 - 作用:支持全文搜索。你搜"索引",能搜到包含"索引"的文章。
- 代价:不能用于精确排序或聚合(Aggregation),因为它被打散了。
-
Keyword 类型(不分词):
- 场景:邮箱地址、身份证号、状态码(如 "SUCCESS")、标签(如 "科技")。
- 比喻:把整句话当作一个不可分割的整体。比如"Elasticsearch 索引与映射"就是一个完整的字符串。
- 作用:支持精确匹配、排序、聚合。你搜"Elasticsearch 索引与映射",必须一字不差才能搜到。
【踩坑预警】 :如果你把一个邮箱字段设置成了 Text,ES 会把它切分成 xxx@qq 和 com,你永远无法精确查询到这个邮箱!
2. 动态映射 vs 显式映射
- 动态映射(Dynamic Mapping) :你往 ES 里扔数据,它自动猜字段类型。
- 优点:开箱即用,非常方便。
- 缺点:容易猜错。比如字符串 "2023-01-01" 可能被猜成 Date,也可能被猜成 Text;数字 "123" 可能被猜成 Long,也可能被猜成 Text。一旦猜错,后续查询会报错或无结果。
- 显式映射(Explicit Mapping) :在创建 Index 前,手动写好 JSON 定义字段类型。
- 建议 :生产环境务必使用显式映射! 就像盖仓库前先画好蓝图,虽然麻烦一点,但能避免后期拆墙重盖。
三、 实战:如何打造一个"智能仓库"?
让我们通过一个电商商品的例子,看看如何设计 Index 和 Mapping。
第一步:设计蓝图(定义 Mapping)
json
PUT /products
{
"mappings": {
"properties": {
"product_id": { "type": "keyword" }, // 商品ID,用于精确匹配
"name": {
"type": "text", // 商品名,支持分词搜索
"analyzer": "ik_max_word" // 使用中文分词器
},
"price": { "type": "float" }, // 价格,用于范围查询和排序
"category": { "type": "keyword" }, // 分类,用于聚合统计
"description": { "type": "text" }, // 详情,全文搜索
"created_at": { "type": "date" }, // 创建时间,用于范围筛选
"tags": { "type": "keyword" }, // 标签数组
"stock": {
"type": "integer"
}
}
}
}
第二步:入库(索引文档)
json
POST /products/_doc/1
{
"product_id": "SKU-2023-001",
"name": "Elasticsearch 实战指南",
"price": 59.9,
"category": "图书",
"description": "一本深入浅出讲解 Elasticsearch 的好书",
"created_at": "2023-10-01T10:00:00Z",
"tags": ["技术", "数据库", "搜索"],
"stock": 100
}
第三步:智能运营(查询与聚合)
有了上面的 Mapping,我们可以做很多"智能"操作:
- 全文搜索 :搜"实战",能命中这本书(因为
name是 text 且分词了)。 - 精确筛选 :
category是 "图书" 的商品(因为category是 keyword)。 - 范围查询:价格在 50 到 100 之间的书。
- 聚合分析 :按
category分组,统计每个分类下有多少本书(因为category是 keyword,适合聚合)。
四、 最佳实践与避坑指南
-
索引即逻辑,也是物理:
- 不要创建成千上万个索引(如每天一个
log-2023-10-01)。ES 的索引是有开销的,太多索引会拖垮集群。建议使用索引别名(Alias)和索引生命周期管理(ILM) ,或者按月/周分索引,并利用*通配符查询。
- 不要创建成千上万个索引(如每天一个
-
Mapping 是"不可逆"的:
- 你可以给 Mapping 增加新字段,但不能修改已有字段的类型(比如把 Text 改成 Keyword)。如果要改,必须重建索引(Reindex)。所以,设计之初要慎重!
-
不要过度映射:
- 并不是所有字段都需要被搜索。如果某个字段只是为了展示(如用户的详细地址),可以设置
"index": false,这样能节省大量磁盘空间和写入性能。
- 并不是所有字段都需要被搜索。如果某个字段只是为了展示(如用户的详细地址),可以设置
-
利用副本(Replica)保障高可用:
- 索引默认有 1 个主分片和 1 个副本。副本不仅能在主分片挂掉时顶上,还能分担搜索压力,提升读取性能。
结语
Elasticsearch 的强大,不在于它能存多少数据,而在于它懂你的数据。
- 索引是地基,决定了数据的物理存放和分布式能力。
- 映射是灵魂,决定了数据的检索方式和分析能力。
当你开始认真思考"这个字段将来怎么查?是模糊搜还是精确匹配?要不要聚合?"的时候,你就已经在为你的数据打造一个真正的"智能仓库"了。
希望这篇文章能帮你理清思路,下一篇我们将聊聊 ES 的另一个核心:搜索原理与 DSL 查询实战。敬请期待!
如果你觉得这篇文章有帮助,欢迎点赞、收藏并分享给你的开发伙伴!