更新符合特定条件的 ElasticSearch 文档

Update ElasticSearch documents matching specific criteria

我想批量更新符合条件的文档。
ES 版本:5.1.1
索引:index_1234
类型:地址
URL: 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'}"
  }
}

即如果 "address" 字段的值为 "temp address" ,我将其替换为 "perm address"

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

假设共有 10 个文档,其中 5 个 "address" 字段为 "temp address",5 个 "address" 字段为 "perm address"

在执行上面的脚本时,它给出以下内容 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 个文档(我已经仔细检查过),但在最终响应中它说 "updated": 10。我期待 "updated":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 的解决方案吗??或者有没有其他方法可以做到这一点? 再次感谢 !

发生这种情况是因为即使您实际上并未修改在 _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"
        }
      }
    }
  ]
  }
  }