更新文档
1.0 版引入
如果您需要更新索引中的文档字段,可以使用更新文档 API 操作。您可以通过指定要放入索引的新数据来完成此操作,也可以在请求正文中包含一个脚本,OpenSearch 将运行该脚本来更新文档。默认情况下,更新操作仅更新索引中存在的文档。如果文档不存在,API 将返回错误。要 upsert 文档(更新现有文档或索引新文档),请使用upsert操作。
在调用更新文档 API 时,您无法显式指定摄取管道。如果索引中定义了 default_pipeline
或 final_pipeline
,则适用以下行为:
- Upsert 操作:当索引新文档时,索引中定义的
default_pipeline
和final_pipeline
将按指定执行。 - 更新操作:更新现有文档时,不建议执行摄取管道,因为它可能会产生错误结果。在更新操作期间运行摄取管道的支持已被弃用,并将在 3.0.0 版本中移除。如果您的索引已定义摄取管道,则更新文档操作将返回以下弃用警告:
the index [sample-index1] has a default ingest pipeline or a final ingest pipeline, the support of the ingest pipelines for update operation causes unexpected result and will be removed in 3.0.0
端点
POST /<index>/_update/<_id>
路径参数
参数 | 类型 | 描述 | 必需 |
---|---|---|---|
<index> | 字符串 | 索引的名称。 | 是 |
<_id> | 字符串 | 要更新的文档 ID。 | 是 |
查询参数
参数 | 类型 | 描述 | 必需 |
---|---|---|---|
if_seq_no | 整数 | 仅当文档具有指定的序列号时才执行更新操作。 | 否 |
if_primary_term | 整数 | 如果文档具有指定的主分片术语,则执行更新操作。 | 否 |
lang | 字符串 | 脚本语言。默认值为 painless 。 | 否 |
require_alias | 布尔型 | 指定目标是否必须是索引别名。默认值为 false 。 | 否 |
refresh | 枚举 | 如果为 true,OpenSearch 会刷新分片,使操作对搜索可见。有效选项包括 true 、false 和 wait_for ,后者告诉 OpenSearch 在执行操作之前等待刷新。默认值为 false 。 | 否 |
retry_on_conflict | 整数 | 如果文档冲突,OpenSearch 应重试操作的次数。默认值为 0。 | 否 |
路由 | 字符串 | 将更新操作路由到特定分片的值。 | 否 |
_source | 布尔值或列表 | 是否在响应正文中包含 _source 字段。默认值为 false 。此参数还支持逗号分隔的源字段列表,以便在查询响应中包含多个源字段。 | 否 |
_source_excludes | 列表 | 要在查询响应中排除的源字段的逗号分隔列表。 | 否 |
_source_includes | 列表 | 要在查询响应中包含的源字段的逗号分隔列表。 | 否 |
timeout | 时间 | 等待集群响应的时间。 | 否 |
wait_for_active_shards | 字符串 | OpenSearch 处理更新请求之前必须可用的活动分片数量。默认值为 1(仅主分片)。设置为 all 或正整数。大于 1 的值需要副本。例如,如果您指定的值为 3,则索引必须有两个副本分布在另外两个节点上,操作才能成功。 | 否 |
请求正文字段
您的请求正文必须包含您要更新文档的信息。如果您只想替换文档中的某些字段,则请求正文必须包含一个 doc
对象,其中包含您要更新的字段。
{
"doc": {
"first_name": "Thomas",
"last_name": "Wayne"
}
}
您还可以使用脚本来告诉 OpenSearch 如何更新文档。
{
"script" : {
"source": "ctx._source.oldValue += params.newValue",
"lang": "painless",
"params" : {
"newValue" : 10
}
}
}
示例请求
更新文档
POST /sample-index1/_update/1
{
"doc": {
"first_name" : "Bruce",
"last_name" : "Wayne"
}
}
使用脚本更新文档
POST /test-index1/_update/1
{
"script" : {
"source": "ctx._source.secret_identity = \"Batman\""
}
}
使用 upsert 操作
Upsert 是一种操作,它根据请求中的信息有条件地更新现有文档或插入新文档。当您不确定文档是否已存在并希望确保无论如何都存在正确内容时,这非常有用。
在以下示例中,如果文档已存在,则 upsert
操作会更新 first_name
和 last_name
字段。如果文档不存在,则使用 upsert
对象中的内容索引一个新文档。
POST /sample-index1/_update/1
{
"doc": {
"first_name": "Martha",
"last_name": "Rivera"
},
"upsert": {
"last_name": "Oliveira",
"age": "31"
}
}
考虑一个包含以下文档的索引:
{
"_index": "sample-index1",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "Bruce",
"last_name": "Wayne"
}
}
在 upsert 操作之后,文档的 first_name
和 last_name
字段已更新。
{
"_index": "sample-index1",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "Martha",
"last_name": "Rivera"
}
}
如果文档不存在于索引中,则会使用 upsert
对象中指定的字段索引一个新文档。
{
"_index": "sample-index1",
"_id": "1",
"_score": 1,
"_source": {
"last_name": "Oliveira",
"age": "31"
}
}
您还可以将 doc_as_upsert
添加到请求中并将其设置为 true
,以使用 doc
字段中的信息执行 upsert 操作。
POST /sample-index1/_update/1
{
"doc": {
"first_name": "Martha",
"last_name": "Oliveira",
"age": "31"
},
"doc_as_upsert": true
}
考虑一个包含以下文档的索引:
{
"_index": "sample-index1",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "Bruce",
"last_name": "Wayne"
}
}
在 upsert 操作之后,文档的 first_name
和 last_name
字段已更新,并添加了 age
字段。如果文档不存在于索引中,则会使用 doc
对象中的字段创建一个新文档。
{
"_index": "sample-index1",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "Martha",
"last_name": "Oliveira",
"age": "31"
}
}
您还可以使用脚本来控制文档的更新方式。通过将 scripted_upsert
参数设置为 true
,您可以指示 OpenSearch 即使文档尚不存在也使用该脚本。这允许您在脚本中定义整个 upsert 逻辑。
在以下示例中,脚本将文档设置为包含特定字段,无论它以前是否存在。
POST /sample-index1/_update/2
{
"scripted_upsert": true,
"script": {
"source": "ctx._source.first_name = params.first_name; ctx._source.last_name = params.last_name; ctx._source.age = params.age;",
"params": {
"first_name": "Selina",
"last_name": "Kyle",
"age": 28
}
},
"upsert": {}
}
如果 ID 为 2
的文档尚不存在,此操作将使用脚本创建它。如果文档确实存在,脚本将更新指定的字段。在两种情况下,结果都是:
{
"_index": "sample-index1",
"_id": "2",
"_score": 1,
"_source": {
"first_name": "Selina",
"last_name": "Kyle",
"age": 28
}
}
当基于标准 doc
的操作不够灵活时,使用 scripted_upsert
可以让您完全控制文档的创建和更新。
示例响应
{
"_index": "sample-index1",
"_id": "1",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"_seq_no": 4,
"_primary_term": 17
}
响应正文字段
字段 | 描述 |
---|---|
_index | 索引的名称。 |
_id | 文档的 ID。 |
_version | 文档的版本。 |
result | 更新操作的结果。 |
_shards | 关于集群分片的详细信息。 |
total | 分片总数。 |
successful | OpenSearch 成功更新文档的分片数量。 |
failed | OpenSearch 未能更新文档的分片数量。 |
_seq_no | 文档索引时分配的序列号。 |
_primary_term | 文档索引时分配的主词。 |