讲讲 Elasticsearch 中的 Index(索引)、Type(类型)、Document(文档)、Field(字段)的概念。
在 Elasticsearch (ES) 中,Index、Type、Document 和 Field 是构建数据存储和检索逻辑的核心概念。
为了让你更容易理解,我们通常会将它们与关系型数据库(如 MySQL)的概念进行类比,但需要注意,随着 ES 版本的迭代,这种类比发生了一些变化(特别是关于 Type 的部分)。
1. 核心概念类比图(RDBMS vs Elasticsearch)
| 概念 | 关系型数据库 (MySQL) | Elasticsearch (旧版/逻辑类比) | Elasticsearch (7.x/8.x 现代版) |
|---|---|---|---|
| 容器 | Database (数据库) | Index (索引) | Index (索引) (更像是一张表) |
| 分类 | Table (表) | Type (类型) | (已移除) (逻辑上一个索引就是一张表) |
| 数据行 | Row (行) | Document (文档) | Document (文档) |
| 数据列 | Column (列) | Field (字段) | Field (字段) |
| 结构定义 | Schema | Mapping | Mapping |
2. 详细概念解析
1. Index(索引)
- 定义:Index 是拥有相似特征的文档的集合。它是 Elasticsearch 中逻辑上的命名空间。
- 类比:
- 在旧版本中,常被比作“数据库”。
- 在现代版本(7.x+)中,它更像数据库中的“表(Table)”。 例如,你可以有一个
product_index(商品索引)或user_index(用户索引)。
- 特点:
- 索引名称必须是小写的(例如
customer,不能是Customer)。 - 一个 ES 集群可以包含任意数量的索引。
- 物理层面:索引的数据被分布在分片(Shards)上,分片可以有副本(Replicas),这是 ES 实现分布式和高可用的基础。
- 索引名称必须是小写的(例如
2. Type(类型)—— 注意:已废弃/移除
- 定义:Type 曾经是 Index 内部的一个逻辑分区,允许你在一个 Index 中存储不同种类的 Document(例如在一个 Index 里存“用户”和“日志”)。
- 现状:
- ES 5.x:一个 Index 可以有多个 Type(开始限制)。
- ES 6.x:一个 Index 只能有一个 Type。
- ES 7.x:Type 被标记为废弃,默认使用
_doc。 - ES 8.x:Type 概念被彻底移除。
- 为什么移除? 因为 Lucene(ES 的底层引擎)没有 Type 的概念。在同一个 Index 中,不同 Type 的同名字段(例如
user.name和product.name)必须拥有相同的物理映射配置。这导致了数据稀疏和混淆。 - 最佳实践:现在请忽略 Type,将一个 Index 视为一张独立的表。
3. Document(文档)
- 定义:Document 是可以被索引的基本信息单元。
- 格式:数据以 JSON (JavaScript Object Notation) 格式表示。
- 类比:相当于关系型数据库中的一行记录(Row)。
- 特点:
- 每个文档都有一个唯一的 ID(可以自己指定,也可以由 ES 自动生成)。
- 虽然文档存储在 Index 中,但实际上它是物理存储在分片中的。
- 文档是无模式(Schema-free)的,意味着你可以直接存入 JSON,但为了性能和搜索准确性,通常会预先定义 Mapping(结构)。
4. Field(字段)
- 定义:Field 是 Document 中的最小数据单元,表现为 JSON 中的 Key-Value 对。
- 类比:相当于关系型数据库中的列(Column)。
- 数据类型:
- 核心类型:Text (文本), Keyword (关键词), Long, Integer, Double, Boolean, Date 等。
- 复杂类型:Object (对象), Nested (嵌套对象)。
- 地理类型:Geo-point, Geo-shape。
- 重要概念:
- Text vs Keyword:这是初学者最容易混淆的。
Text:会被分词(Analyzed)。例如 "Apple Store" 会被拆分成 "apple" 和 "store",用于全文检索。Keyword:不分词,原样存储。例如 "Apple Store" 必须完全匹配才能搜到,用于聚合、排序和精确匹配。
- Text vs Keyword:这是初学者最容易混淆的。
3. 举个栗子
假设我们要存储一个电商网站的商品信息。
- Index: 我们创建一个名为
products的索引。 - Document: 我们插入一条商品数据(JSON)。
- Field: JSON 里面的
name,price,tags就是字段。
json
// 这是一条 Document
{
"_index": "products", // 属于 products 索引
"_id": "1001", // 文档唯一 ID
"_source": { // 实际的数据内容
"name": "iPhone 15", // Field: 字段名为 name,值为 iPhone 15 (Text类型)
"price": 5999.00, // Field: 价格 (Double类型)
"is_available": true, // Field: 是否有货 (Boolean类型)
"tags": ["phone", "apple"], // Field: 标签 (Array/Keyword类型)
"created_at": "2023-09-12" // Field: 创建时间 (Date类型)
}
}
总结
- Index 是书架(存放数据的地方,现在相当于一张表)。
- Type 是书架上的分类标签(因为容易搞混,已经被撕掉了,现在一个书架只放一类书)。
- Document 是一本具体的书(一条具体的数据)。
- Field 是书里的书名、作者、页数等属性(数据的具体属性)。