更新数据时document的变化过程
Elasticsearch(ES)存储数据的结构
数据结构
-
Index(索引):
- 索引是Elasticsearch中存储数据的基本单位,类似于传统关系型数据库中的数据库。一个索引包含一组具有相同结构的文档。
-
Document(文档):
- 文档是Elasticsearch中存储的基本数据单元,类似于关系型数据库中的行。每个文档是一个JSON对象,包含多个字段和值。
-
Type(类型):
- 在Elasticsearch 7.x及以后版本中,类型的概念已经被废弃。在早期版本中,一个索引可以包含多个类型,每个类型包含一组相同结构的文档。
-
Field(字段):
- 字段是文档中的一个键值对,表示文档的一个属性。
-
Mapping(映射):
- 映射定义了索引中字段的类型及其行为,例如字段是否可以被搜索,是否需要存储等。
示例文档结构
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA"
}
}
更新数据时document的变化
在Elasticsearch中,更新文档时会经历以下几个步骤:
-
查找文档:
- Elasticsearch首先根据文档ID查找需要更新的文档。
-
创建新版本:
- Elasticsearch不会在原地修改文档,而是创建一个新版本的文档。新文档包含更新后的内容,同时版本号增加。
-
标记旧版本为删除:
- 旧版本的文档会被标记为删除,但不会立即物理删除。这是为了保证数据的一致性和可靠性。
-
索引新版本文档:
- 新版本的文档被索引并存储在Elasticsearch中,新的索引条目被添加到倒排索引中。
-
更新文档元数据:
- 更新文档的元数据,包括版本号、更新时间等。
-
旧文档删除:
- 旧文档的物理删除由Elasticsearch的后台合并(merge)进程在适当的时候执行,以释放存储空间。
更新示例
假设我们有一个文档,初始内容如下:
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com"
}
我们想更新文档,增加一个新的字段phone
:
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"phone": "555-1234"
}
更新请求:
POST /index_name/_update/document_id
{
"doc": {
"phone": "555-1234"
}
}
更新后的文档存储在Elasticsearch中,原始文档被标记为删除,并最终在后台被物理删除。
注意事项
- 版本冲突:如果同时有多个更新请求针对同一文档,可能会发生版本冲突。Elasticsearch使用乐观并发控制来处理这种情况。
- 部分更新:Elasticsearch允许部分更新文档,而不需要发送整个文档。这通过
_update
API实现,内部仍然是重新索引整个文档。 - 性能影响:频繁更新会导致大量旧版本的文档被标记为删除,影响性能。定期优化和管理索引是必要的。
通过理解Elasticsearch的数据结构和更新过程,可以更有效地利用其功能进行数据存储和管理。