批量
1.0 版引入
批量操作允许您在单个请求中添加、更新或删除多个文档。与单独的 OpenSearch 索引请求相比,批量操作具有显著的性能优势。在实际操作中,我们建议将索引操作批量处理到批量请求中。
从 OpenSearch 2.9 开始,在使用批量操作索引文档时,文档的 _id
大小必须小于或等于 512 字节。
端点
POST _bulk
POST <index>/_bulk
在路径中指定索引意味着您无需将其包含在请求正文中。
OpenSearch 也接受对 _bulk
路径的 PUT 请求,但我们强烈建议使用 POST。PUT 的公认用法——在给定路径添加或替换单个资源——对于批量请求没有意义。
查询参数
所有参数都是可选的。
参数 | 类型 | 描述 |
---|---|---|
pipeline | 字符串 | 用于预处理文档的管道 ID。 |
refresh | 枚举 | 是否在执行索引操作后刷新受影响的分片。默认值为 false 。true 会导致更改立即显示在搜索结果中,但会降低集群性能。wait_for 会等待刷新。请求返回时间会更长,但集群性能不会降低。 |
require_alias | 布尔型 | 设置为 true 要求所有操作都以索引别名而非索引为目标。默认值为 false 。 |
路由 | 字符串 | 将请求路由到指定分片。 |
timeout | 时间 | 等待请求返回的时间。默认值为 1m 。 |
wait_for_active_shards | 字符串 | 指定在 OpenSearch 处理批量请求之前必须可用的活动分片数量。默认值为 1 (仅主分片)。设置为 all 或正整数。大于 1 的值需要副本。例如,如果指定值为 3,则索引必须在 2 个附加节点上分布 2 个副本,请求才能成功。 |
请求正文
批量请求正文遵循此模式
Action and metadata\n
Optional document\n
Action and metadata\n
Optional document\n
可选的 JSON 文档不需要被最小化——空格是可以的——但它必须在一行上。OpenSearch 使用换行符来解析批量请求,并要求请求正文以换行符结尾。
所有操作都支持相同的元数据:_index
、_id
和 _require_alias
。如果您不提供 ID,OpenSearch 会自动生成一个,这可能会使以后更新文档变得困难。
创建
如果文档不存在则创建,否则返回错误。下一行必须包含 JSON 文档
{ "create": { "_index": "movies", "_id": "tt1392214" } }
{ "title": "Prisoners", "year": 2013 }
删除
如果文档存在,此操作将删除该文档。如果文档不存在,OpenSearch 不会返回错误,而是在 result
下返回 not_found
。删除操作不需要下一行有文档
{ "delete": { "_index": "movies", "_id": "tt2229499" } }
索引
索引操作会在文档不存在时创建文档,并在文档已存在时替换文档。下一行必须包含 JSON 文档
{ "index": { "_index": "movies", "_id": "tt1979320" } }
{ "title": "Rush", "year": 2013}
更新
默认情况下,此操作会更新现有文档,如果文档不存在则返回错误。下一行必须包含完整或部分 JSON 文档,具体取决于您要更新文档的多少内容
{ "update": { "_index": "movies", "_id": "tt0816711" } }
{ "doc" : { "title": "World War Z" } }
插入更新
要插入更新文档,请将 doc_as_upsert
设置为 true
。如果文档存在,则更新它;如果文档不存在,则使用 doc
字段中指定的参数索引新文档
{ "update": { "_index": "movies", "_id": "tt0816711" } }
{ "doc" : { "title": "World War Z" }, "doc_as_upsert": true }
脚本
您可以通过使用文档中的 source
或 id
定义脚本来指定更复杂的文档更新
{ "update": { "_index": "movies", "_id": "tt0816711" } }
{ "script" : { "source": "ctx._source.title = \"World War Z\"" } }
脚本化插入更新
您可以通过将 scripted_upsert
设置为 true
来使用脚本在一个操作中插入或更新文档。这确保了无论文档是否存在,脚本都会运行。如果文档不存在,脚本将从头开始初始化其内容。
POST _bulk
{ "update": { "_index": "movies", "_id": "tt0816711" } }
{ "script": { "source": "ctx._source.title = params.title; ctx._source.genre = params.genre;", "params": { "title": "World War Z", "genre": "Action" } }, "upsert": {}, "scripted_upsert": true }
此操作会在 ID 为 tt0816711
的文档不存在时,使用脚本中的逻辑创建一个新文档。如果文档确实存在,则应用相同的脚本来更新其字段。
请求示例
POST _bulk
{ "delete": { "_index": "movies", "_id": "tt2229499" } }
{ "index": { "_index": "movies", "_id": "tt1979320" } }
{ "title": "Rush", "year": 2013 }
{ "create": { "_index": "movies", "_id": "tt1392214" } }
{ "title": "Prisoners", "year": 2013 }
{ "update": { "_index": "movies", "_id": "tt0816711" } }
{ "doc" : { "title": "World War Z" } }
示例响应
在响应中,请特别注意顶层 errors
布尔值。如果为 true,您可以迭代各个操作以获取更详细的信息。
{
"took": 11,
"errors": true,
"items": [
{
"index": {
"_index": "movies",
"_id": "tt1979320",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1,
"status": 201
}
},
{
"create": {
"_index": "movies",
"_id": "tt1392214",
"status": 409,
"error": {
"type": "version_conflict_engine_exception",
"reason": "[tt1392214]: version conflict, document already exists (current version [1])",
"index": "movies",
"shard": "0",
"index_uuid": "yhizhusbSWmP0G7OJnmcLg"
}
}
},
{
"update": {
"_index": "movies",
"_id": "tt0816711",
"status": 404,
"error": {
"type": "document_missing_exception",
"reason": "[_doc][tt0816711]: document missing",
"index": "movies",
"shard": "0",
"index_uuid": "yhizhusbSWmP0G7OJnmcLg"
}
}
}
]
}