更新符合特定条件的 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"
}
}
}
]
}
}
我想批量更新符合条件的文档。
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"
}
}
}
]
}
}