如何操作 Elasticsearch 进行文档的更新和删除?
Elasticsearch文档操作指南:介绍了更新、删除文档的API使用。更新包括部分更新(_update API)和全量替换(PUT),支持脚本更新和upsert操作。删除文档使用DELETE方法,会保留版本号。另提供按查询条件批量更新(_update_by_query)和删除(_delete_by_query)功能,后者需谨慎使用。建议优先选择部分更新,全量替换易丢失字段,批量删除属于高危操作
Elasticsearch 提供了强大的 RESTful API 来执行这些操作,通常使用 POST、PUT 和 DELETE HTTP 方法。
1. 更新文档 (Update)
更新文档主要有两种方式:部分更新 和 全量替换。
a) 部分更新 (_update API)
这是最常用的更新方式,允许你只修改文档中的特定字段,而不需要重新索引整个文档。它遵循“获取-修改-重新索引”的流程,但所有操作在单个 API 调用中原子性完成。
- HTTP 方法:
POST - 端点格式:
<index_name>/_update/<document_id>
请求体: 主要使用 doc 参数来指定要更新的字段。
示例: 将 ID 为 101 的文档中的 title 字段改为 “Updated Title”,并添加一个新字段 tags。
POST my_index/_update/101
{
"doc": {
"title": "Updated Title",
"tags": ["search", "elasticsearch"]
}
}
响应:
{
"_index" : "my_index",
"_id" : "101",
"_version" : 2, // 版本号会增加
"result" : "updated" // 表示更新成功
}
高级特性:
-
脚本更新: 你可以使用 Painless 脚本进行更复杂的逻辑更新。
POST my_index/_update/101 { "script" : { "source": "ctx._source.views += params.increment", "params": { "increment": 1 } } }(上述脚本将
views字段的值增加 1) -
upsert: 如果文档不存在,则执行插入操作。
POST my_index/_update/102 { "doc": { "title": "A New Document" }, "upsert": { // 如果 ID 102 不存在,则插入 upsert 的内容 "title": "An Upserted Document", "created_at": "2023-10-25" } }
b) 全量替换
虽然叫“更新”,但本质上是先删除旧文档,再索引一个新文档。你需要提供完整的文档内容。
- HTTP 方法:
PUT或POST - 端点格式:
<index_name>/_doc/<document_id>
示例:
PUT my_index/_doc/101
{
"title": "A Completely New Title",
"content": "This is the entire new content of the document.",
"new_field": "This field didn't exist before."
}
注意: 执行此操作后,原文档中所有未在新请求体中指定的字段都将丢失。
2. 删除文档 (Delete)
删除操作相对直接,你需要指定索引和文档的 ID。
- HTTP 方法:
DELETE - 端点格式:
<index_name>/_doc/<document_id>
示例: 删除 ID 为 101 的文档。
DELETE my_index/_doc/101
响应:
{
"_index" : "my_index",
"_id" : "101",
"_version" : 3, // 版本号依然会增加,这对于并发控制很重要
"result" : "deleted" // 表示删除成功
}
重要注意事项:
- 找不到文档: 如果你尝试删除一个不存在的文档,Elasticsearch 会返回
"result" : "not_found",但 HTTP 状态码仍然是404。这不算是错误,只是表明要执行的操作无需执行。 - 版本控制: 删除操作也会增加文档的版本号,这是一种乐观锁机制,防止在删除过程中基于旧版本数据的并发修改。
- 物理删除: 删除文档后,它并不会立即从磁盘上物理清除,而是被标记为已删除。这些数据会在后续段合并(Segment Merge)时被真正清理掉。
3. 按查询条件更新或删除
你可以使用 Query DSL 来匹配符合特定条件的文档,然后对它们进行批量更新或删除。
a) 按查询更新 (_update_by_query)
- 端点:
<index_name>/_update_by_query
示例: 将所有由 John 创作的文档的 status 字段设置为 reviewed。
POST my_index/_update_by_query
{
"query": {
"term": { // 查询条件,匹配 author 字段为 John 的文档
"author": "John"
}
},
"script": {
"source": "ctx._source.status = 'reviewed'"
}
}
b) 按查询删除 (_delete_by_query)
- 端点:
<index_name>/_delete_by_query
示例: 删除所有 status 字段为 obsolete 的文档。
POST my_index/_delete_by_query
{
"query": {
"term": {
"status": "obsolete"
}
}
}
警告: _delete_by_query 是一个威力巨大的操作,执行前务必再三确认查询条件是否正确,以免误删重要数据。建议先在测试环境验证,或使用 dry_run 参数进行试运行。
总结与最佳实践
| 操作 | 常用 API | 说明 |
|---|---|---|
| 部分更新 | POST <index>/_update/<id> |
推荐。高效,只传输变化的字段。 |
| 全量替换 | PUT <index>/_doc/<id> |
低效,需要传输完整文档。易丢失字段,慎用。 |
| 根据ID删除 | DELETE <index>/_doc/<id> |
精确删除指定文档。 |
| 批量更新 | _update_by_query |
根据查询条件批量更新文档。 |
| 批量删除 | _delete_by_query |
高危操作。根据查询条件批量删除文档,需极其谨慎。 |
- 工具: 可以使用 Kibana 的 Dev Tools 控制台来非常方便地执行上述所有 API 调用。
- 客户端: 在实际应用中,应使用 Elasticsearch 官方提供的各种语言客户端(如 Java、Python High-Level Client)来执行这些操作,它们提供了更友好的封装和错误处理。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)