Elasticsearch 文档(Document)详解
在 Elasticsearch 中,文档(Document) 是数据存储和检索的基本单位。理解文档的结构、特性以及其在索引、搜索中的作用,是掌握 Elasticsearch 的核心基础。本文将全面详解 Elasticsearch 文档的概念、结构、操作方式及最佳实践。
一、什么是文档(Document)?
在 Elasticsearch 中,文档 是一条可被索引和搜索的 JSON 格式数据记录。它类似于关系型数据库中的一行记录(Row),但以 JSON 对象的形式存在,具有灵活的结构。
示例文档:
{
"user": "张三",
"age": 30,
"email": "zhangsan@example.com",
"timestamp": "2024-04-01T10:00:00Z",
"address": {
"city": "北京",
"district": "朝阳区"
},
"tags": ["developer", "java"]
}
二、文档的核心特性
-
JSON 格式
- 所有文档必须是有效的 JSON。
- 支持嵌套对象(如
address)、数组(如tags)等复杂结构。
-
无模式(Schema-less)
- Elasticsearch 是动态映射(Dynamic Mapping) 的,首次插入文档时,Elasticsearch 会自动推断字段类型(如字符串、数字、日期等)并创建映射(Mapping)。
- 也可以提前定义 Mapping 以控制字段类型。
-
唯一标识(_id)
- 每个文档都有一个唯一 ID,用于标识和检索。
- 可由用户指定,也可由 Elasticsearch 自动生成(如 UUID)。
-
存储在索引(Index)中
- 文档必须属于一个索引(Index),索引类似于数据库中的“表”。
- 一个索引可以包含多个文档。
-
版本控制(_version)
- 每次更新文档,其
_version自动递增,用于并发控制和乐观锁。
- 每次更新文档,其
-
元数据字段(Metadata Fields)
- Elasticsearch 为每个文档维护一些元数据字段,常见的有:
_index:文档所属的索引。_id:文档的唯一 ID。_type:文档类型(7.x 后已废弃,统一为_doc)。_version:文档版本号。_source:原始 JSON 数据。_score:相关性评分(搜索时使用)。
- Elasticsearch 为每个文档维护一些元数据字段,常见的有:
三、文档的结构
一个完整的文档在 Elasticsearch 中由两部分组成:
1. 元数据(Metadata)
由 Elasticsearch 自动管理,包含索引、ID、版本等信息。
2. 源数据(_source)
即用户提交的原始 JSON 数据,存储在 _source 字段中。默认情况下,Elasticsearch 会保存 _source,用于:
- 返回搜索结果。
- 更新文档时重新索引。
- 高亮、聚合等高级功能。
⚠️ 注意:可以配置不存储
_source,但会限制部分功能。
四、文档的基本操作(CRUD)
1. 创建文档(Create)
自动生成 ID:
POST /users/_doc
{
"user": "李四",
"age": 25
}
指定 ID:
PUT /users/_doc/1
{
"user": "王五",
"age": 28
}
2. 读取文档(Read)
GET /users/_doc/1
返回示例:
{
"_index": "users",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"user": "王五",
"age": 28
}
}
3. 更新文档(Update)
POST /users/_update/1
{
"doc": {
"age": 29
}
}
更新操作实际上是“重新索引”(reindex):获取原文档,合并更改,然后替换旧文档。
4. 删除文档(Delete)
DELETE /users/_doc/1
五、文档的内部机制
1. _source 字段
- 默认存储原始 JSON。
- 可在 Mapping 中配置是否存储、是否压缩、是否启用等。
2. 字段映射(Mapping)
- 定义字段的数据类型(text、keyword、date、integer 等)。
- 影响分词、排序、聚合等行为。
示例 Mapping:
PUT /users
{
"mappings": {
"properties": {
"user": { "type": "text" },
"email": { "type": "keyword" },
"timestamp": { "type": "date" }
}
}
}
3. 动态 vs 静态映射
- 动态映射:自动推断字段类型(默认开启)。
- 静态映射:手动定义字段类型,避免类型冲突。
六、文档的批量操作(Bulk API)
批量操作可提高性能,减少网络开销。
POST /_bulk
{ "index" : { "_index" : "users", "_id" : "2" } }
{ "user": "赵六", "age": 32 }
{ "update" : { "_index" : "users", "_id" : "1" } }
{ "doc" : { "age" : 30 } }
{ "delete" : { "_index" : "users", "_id" : "3" } }
每行必须是独立的 JSON,且换行符分隔。
七、文档的最佳实践
-
合理设计文档结构
- 避免过深的嵌套。
- 使用
join或nested类型处理复杂关系(如父子文档)。 - 考虑 denormalization(反规范化)以提升查询性能。
-
控制文档大小
- 单文档建议不超过几 KB 到几十 KB。
- 大文档影响性能(加载、传输、GC)。
-
启用
_source- 除非有特殊需求(如节省磁盘),否则保留
_source。
- 除非有特殊需求(如节省磁盘),否则保留
-
使用合适的字段类型
text用于全文搜索(会分词)。keyword用于精确匹配、排序、聚合。
-
避免频繁更新
- 更新本质是删除 + 重建,开销较大。
- 高频更新场景可考虑使用
updateAPI 的doc_as_upsert。
八、常见问题
1. 文档更新后 _version 会变吗?
是的,每次更新(包括创建、删除)都会使 _version +1。
2. 可以不保存 _source 吗?
可以,但会失去:
- 获取原始数据的能力。
updateAPI 的便利性。- 高亮、脚本字段等功能受限。
3. 文档支持事务吗?
Elasticsearch 不支持传统数据库的 ACID 事务,但单文档操作是原子的。多文档操作需通过应用层控制一致性。
九、总结
| 特性 | 说明 |
|---|---|
| 格式 | JSON |
| 存储单位 | _source 字段 |
| 唯一标识 | _id |
| 所属 | 索引(Index) |
| 操作 | CRUD + Bulk |
| 映射 | 动态或静态定义字段类型 |
| 版本控制 | _version 实现乐观锁 |
文档是 Elasticsearch 的核心,理解其结构和行为,有助于设计高效的索引策略、提升搜索性能,并避免常见陷阱。
📌 扩展阅读建议:
- Elasticsearch 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html
- Mapping 类型详解
- Nested vs Object 类型对比
- Ingest Pipeline 预处理文档
467

被折叠的 条评论
为什么被折叠?



