【问题标题】:Elasticsearch partial update script: Clear array and replace with new valuesElasticsearch 部分更新脚本:清除数组并替换为新值
【发布时间】:2025-11-24 14:20:12
【问题描述】:

我有如下文件:

{
  MyProp: ["lorem", "ipsum", "dolor"]
  ... lots of stuff here ...
}

我的文档可能非常大(但这些 MyProp 字段不是),并且从头开始生成成本很高。

有时我需要批量更新这些 - 因此进行 部分 更新(以节省“索引客户端”处理能力和带宽,从而节省时间)并替换 MyProp 值将是有益的新的价值观。

原始文件示例:

{
  MyProp: ["lorem", "ipsum", "dolor"]
  ... lots of stuff here ...
}

更新文档的示例(或者更确切地说应该是它的外观):

{
  MyProp: ["dolor", "sit"]
  ... lots of stuff here ...
}

据我所知,这包括脚本。

谁能告诉我剩下的谜题?

赏金添加:

如果可能的话,我还想要一些关于如何在批处理语句中制作这些内容的说明。

【问题讨论】:

  • 你能展示一个你想做的更新吗?
  • @Val,完成!谢谢
  • 您愿意一次在一个文档中更新MyProp,还是在多个文档中更新?
  • 大多数时候,他们需要独特的价值。
  • 什么 Elasticsearch 版本?

标签: elasticsearch


【解决方案1】:

您可以使用update by query API 进行批量更新。这从 ES 2.3 开始有效,否则你需要install a plugin

POST index/_update_by_query
{
  "script": {
    "inline": "ctx._source.myProp += newProp",
    "params": {
      "newProp": "sit"
    }
  },
  "query": {
    "match_all": {}
  }
}

您当然可以使用任何您想要的查询来选择需要更新MyProp 的文档。例如,您可以通过查询选择具有某些特定 MyProp 值的文档以进行替换。

以上只会给现有数组添加一个新值。如果你需要完全替换MyProp数组,那么你也可以把脚本改成这样:

POST index/_update_by_query
{
  "script": {
    "inline": "ctx._source.myProp = newProps",
    "params": {
      "newProps": ["dolor", "sit"]
    }
  },
  "query": {
    "match_all": {}
  }
}

请注意,您还需要enable dynamic scripting 才能使其正常工作。

更新

如果您只是想更新单个文档,可以使用partial document update API,如下所示:

POST test/type1/1/_update
{
    "doc" : {
        "MyProp" : ["dolor", "sit"]
    }
}

这将有效地替换指定文档中的MyProp 数组。

如果你想走批量路线,你不需要编写脚本来实现你想要的:

POST index/type/_bulk
{ "update" : {"_id" : "1"} }
{ "doc" : {"MyProp" : ["dolor", "sit"] } }
{ "update" : {"_id" : "2"} }
{ "doc" : {"MyProp" : ["dolor", "sit"] } }

【讨论】:

  • 这会有效清除现有值吗?
  • 很抱歉打扰您。您能否举例说明如何在非批处理模式下执行此操作? (为清楚起见)
  • 再次抱歉。对于单个文档部分更新。您确定这会替换数组并清除现有值吗?
  • 是的,它将完全替换数组并清除以前的值。
  • 所以只发布带有部分 api 更新的批量就可以了?我不确定您的第一个示例是否适用,因为我从不将新值推送到现有值,只是替换。我将文档理解为他们添加新值而不删除旧值。
【解决方案2】:

_bulk 更新对您有用吗?

POST test/type1/_bulk
{"update":{"_id":1}}
{"script":{"inline":"ctx._source.MyProp += new_param","params":{"new_param":"bla"},"lang":"groovy"}}
{"update":{"_id":2}}
{"script":{"inline":"ctx._source.MyProp += new_param","params":{"new_param":"bla"},"lang":"groovy"}}
{"update":{"_id":3}}
{"script":{"inline":"ctx._source.MyProp += new_param","params":{"new_param":"bla"},"lang":"groovy"}}
....

您还需要为groovy 启用内联脚本。上面的操作是将bla 值添加到MyProp 字段中列出的文档中。当然,根据您的要求,可以在该脚本中执行许多其他更改。

【讨论】: