elasticsearch upsert 使用
文章目录
- `upsert` 的工作原理
- 基本语法
- 示例 1:简单的 `upsert` 操作
- 示例 2:使用脚本进行 `upsert`
- 示例 3:使用 `upsert` 插入数组或对象
- 常见的 `upsert` 用法场景
- 注意事项
- 小结
在 Elasticsearch 中,upsert
是一个常见的操作,用于执行文档的 更新 或 插入,具体行为取决于目标文档是否存在:
- 如果文档 不存在,
upsert
将创建该文档。 - 如果文档 已经存在,
upsert
将对该文档进行 更新。
upsert
操作通常用于合并或更新文档数据,确保目标文档的存在,同时避免因为文档不存在而导致的错误。
upsert
的工作原理
upsert
主要与 Elasticsearch 的 更新 API(_update
)结合使用。在执行 upsert
时,你可以提供两部分内容:
doc
:表示更新文档的内容。upsert
:表示在文档不存在时要插入的文档内容。
基本语法
POST /<index>/_update/<document_id>
{
"doc": {
"field1": "value1",
"field2": "value2"
},
"upsert": {
"field1": "default_value1",
"field2": "default_value2"
}
}
index
:目标索引的名称。document_id
:文档的 ID。doc
:如果文档存在,更新该文档的数据。upsert
:如果文档不存在,插入这个默认数据。
示例 1:简单的 upsert
操作
假设你有一个名为 users
的索引,并且你想通过文档 ID 来插入或更新用户信息。以下操作将会:
- 如果文档存在,则更新该文档。
- 如果文档不存在,则插入新的文档。
POST /users/_update/1
{
"doc": {
"age": 30
},
"upsert": {
"name": "John Doe",
"age": 30
}
}
在这个例子中:
- 如果文档 ID 为
1
的用户存在,age
字段将被更新为30
。 - 如果文档 ID 为
1
的用户不存在,name
和age
字段将被插入并创建新的文档。
示例 2:使用脚本进行 upsert
有时你可能需要使用脚本来动态更新文档的字段。你可以在 doc
中使用脚本来更新字段值,或者在 upsert
中插入一个文档。
POST /users/_update/1
{
"script": {
"source": "ctx._source.age += 1",
"lang": "painless"
},
"upsert": {
"name": "Jane Doe",
"age": 25
}
}
在这个例子中:
- 如果文档 ID 为
1
的用户存在,age
字段会增加 1。 - 如果文档 ID 为
1
的用户不存在,则插入一个新的用户,name
为"Jane Doe"
,age
为25
。
示例 3:使用 upsert
插入数组或对象
如果文档中的字段是数组或对象,你也可以使用 upsert
来插入复杂的数据结构。
假设你有一个 orders
索引,文档包含一个订单的详情。你想通过 upsert
插入一个新的订单或者更新现有订单。
POST /orders/_update/123
{
"doc": {
"status": "shipped",
"shipped_date": "2024-12-20"
},
"upsert": {
"order_id": 123,
"status": "pending",
"items": [
{
"product_id": 1,
"quantity": 2
}
]
}
}
在这个例子中:
- 如果文档 ID 为
123
的订单存在,status
和shipped_date
字段将被更新。 - 如果文档 ID 为
123
的订单不存在,则插入一个新的订单,status
为"pending"
,并包含一个初始的订单项。
常见的 upsert
用法场景
- 合并数据:当你有一个包含多个文档的场景时,使用
upsert
可以避免重复插入。如果文档已经存在,则更新已有的字段,如果不存在则插入新文档。 - 计数器或累积值:可以在文档中维护计数器或累积值。例如,当一个页面被访问时,你可以使用
upsert
来增加访问次数。如果文档不存在,则插入一个新的文档并设置计数器为 1。 - 索引创建时:在某些情况下,你可能希望在文档不存在时自动创建文档,例如,当插入日志数据时,日志条目可以通过
upsert
自动插入或者更新。
注意事项
upsert
是基于文档 ID 的操作,确保每个文档具有唯一的 ID。如果你使用相同的文档 ID 执行多个upsert
操作,将会对该文档执行更新操作。upsert
操作的doc
部分是增量更新的,它只会更新已存在字段,不会影响不存在的字段。如果你希望替换整个文档,可以使用doc_as_upsert
(通过update
API)将doc
作为插入文档的内容。
小结
upsert
是 Elasticsearch 中用于确保文档存在的操作,如果文档不存在,则会创建它。如果文档已存在,则会更新它。- 它结合了 更新 和 插入 的功能,确保数据的完整性。
- 可以通过脚本进一步动态更新文档内容,或者在插入新文档时使用默认数据。
upsert
非常适用于那些需要频繁更新或插入数据的场景,特别是在你不确定文档是否已经存在的情况下。