【问题标题】:Update ElasticSearch documents matching specific criteria更新符合特定条件的 ElasticSearch 文档
【发布时间】:2017-10-11 12:56:02
【问题描述】:

我想批量更新符合条件的文档。
ES 版本:5.1.1
索引:index_1234
类型:地址
网址:POST http://localhost:9200/index_1234/addresses/_update_by_query
有效载荷:

{
    "id":1,
    "address":"temp address"
}

我正在使用以下内联脚本来更新文档

{
  "script": {
     "inline": "if(ctx._source.containsKey(\"address\") && ctx._source.address == "temp address"){ctx._source.address='perm address'}"
  }
}

即如果“地址”字段的值为“临时地址”,我将其替换为“永久地址”

此脚本完美运行,仅更新匹配的文档。 但是我有一个疑问

假设总共有 10 个文档,其中 5 个具有“地址”字段作为“临时地址”,5 个具有“地址”字段作为“永久地址”

在执行上述脚本时,它会给出以下 o/p

{
    "took": 131,
    "timed_out": false,
    "total": 10,
    **"updated": 10**,
    "deleted": 0,
    "batches": 1,
    "version_conflicts": 0,
    "noops": 0,
    "retries": {
        "bulk": 0,
        "search": 0
    },
    "throttled_millis": 0,
    "requests_per_second": -1,
    "throttled_until_millis": 0,
    "failures": []
}

所以虽然它只更新了 5 个文档(我已经仔细检查过),但在最终回复中它说“更新”:10。我期待“更新”:5,我错过了什么吗? 它是否在更新其他内容?我可以看到所有文档的“_version”都得到了更新,即使是没有匹配字符串的文档。
提前致谢 !

更新:

非常感谢 Mike 的快速回复 :)
根据 Mike 字段检查,更新查询应更新如下。

"query": {
  "exists": {
    "field": "address"
  }
}

但是还有 1 个问题。
最初,为了简单起见,我将字段保持在最低限度。 实际上有效载荷中有很多字段,我想根据某些条件更新其中的 3 个。

所以,payload如下

{
    "id":12,
    "address":"temp address",
    "email":"temp email",
    "phone":"temp phone",
    .
    .
    .
}

我正在使用以下脚本来更新所有 3 个字段

{
  "script": {
     "inline": "if(ctx._source.containsKey(\"address\") && ctx._source.address == "temp address"){ctx._source.address='perm address'}if(ctx._source.containsKey(\"email\") && ctx._source.email == "temp email"){ctx._source.email='perm email'}if(ctx._source.containsKey(\"phone\") && ctx._source.phone == "temp phone"){ctx._source.phone='perm phone'}"
  }
}

我们可以为多个字段更新 Mike 的解决方案吗?或者有没有其他方法可以做到这一点? 再次感谢 !

【问题讨论】:

    标签: elasticsearch elasticsearch-5


    【解决方案1】:

    发生这种情况是因为即使您实际上并未修改在 _update_by_query 请求中检索到的所有文档,它们至少在您的查询中被计为命中。

    不要在更新查询中检查您的字段,而是将此存在查询添加到您的更新请求中:

    "query": {
      "exists": {
        "field": "address"
      }
    }
    

    编辑以回复更新后的问题: 如果您想更新 3 个字段,您很可能会最轻松地通过单个脚本同时进行 3 次修改。如上所示,计数并不能真正反映对文档所做的实际修改。如果绝对需要计数,您可以这样做(它会过滤到具有这 3 个中的任何一个的任何文档。)

    "query": {
      "bool": {
        "minimum_should_match": 1,
        "should": [
          {
            "term": {
              "address": {
                "value": "temp address"
              }
            }
          },
          {
            "term": {
              "email": {
                "value": "temp email"
              }
            }
          },
          {
          "term": {
            "phone": {
              "value": "temp phone"
            }
          }
        }
      ]
      }
      }
    

    【讨论】:

    • 嗨,迈克,感谢您的快速回复 :),我现在已经更新了问题,请您看看“更新”部分。 ??
    • 谢谢迈克!但我相信当且仅当所有 3 个条件都匹配时,内联脚本才会执行,可能存在仅匹配 1 个或 2 个或所有 3 个条件的情况。
    • @SSG 它应该匹配其中任何一个。我将术语查询包装在顶部的 should 容器中。由于“minimum_should_match”为 1(这是默认设置,我将其配置为用于演示),任何符合这些语句的任何文档都将成为结果集的一部分。然后,您的更新脚本将可以访问这些结果。
    猜你喜欢
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    相关资源
    最近更新 更多