Link Search Menu Expand Document Documentation Menu

更新文档

1.0 版引入

如果您需要更新索引中的文档字段,可以使用更新文档 API 操作。您可以通过指定要放入索引的新数据来完成此操作,也可以在请求正文中包含一个脚本,OpenSearch 将运行该脚本来更新文档。默认情况下,更新操作仅更新索引中存在的文档。如果文档不存在,API 将返回错误。要 upsert 文档(更新现有文档或索引新文档),请使用upsert操作。

在调用更新文档 API 时,您无法显式指定摄取管道。如果索引中定义了 default_pipelinefinal_pipeline,则适用以下行为:

  • Upsert 操作:当索引新文档时,索引中定义的 default_pipelinefinal_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 会刷新分片,使操作对搜索可见。有效选项包括 truefalsewait_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_namelast_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_namelast_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_namelast_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 文档索引时分配的主词。
剩余 350 字符

有问题?

想贡献?