我正在尝试创建或更新一个我没有 ID 的文档。所以我目前正在做的是搜索/获取现有的(或不存在的)文档,更新它并将其推回,它正在工作。
但我想一次性完成这一切。
我读过有关通过查询更新的信息,它看起来不适用于这种情况。我也尝试过使用脚本,但只找到了更新参考(所以我需要ID)。
不确定这在 ES 上是否可行。
非常感谢任何帮助/提示。
谢谢
更多信息:
就我而言,我与 ID 没有直接关系,这就是我打算通过查询更新的原因
我的文档很简单,如下所示:
{
"text": "some text",
"type": "a real type",
"occurences": 2
}
Run Code Online (Sandbox Code Playgroud)
所以我必须通过文本键和键入键来匹配它。如果不存在则添加一个新文档(出现次数为1),如果找到则更新出现次数更新为 3。
根据 的文档update_by_query,应该可以执行以下操作:
POST /test/type/_update_by_query?conflicts=proceed
{
"query": {
"bool": {
"must": [
{"match_phrase": {"text": "some text"}},
{"match_phrase": {"type": "a real type"}}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我不知道如何离开这里。
当我使用动态生成的 id 而不存储它们时,我偶然发现了确切的问题。
我相信这是不可能在一个查询中完成的,但您可以使用_update_by_query并检查响应正文中的更新计数,如果它为 0 那么您可以安全地插入新实例。
所以在你的情况下它会是这样的:
POST /test/type/_update_by_query
{
"script": {
"inline": "ctx._source.occurences++"
},
"query": {
"bool": {
"must": [
{"match_phrase": {"text": "some text"}},
{"match_phrase": {"type": "a real type"}}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
响应可能是:
{
"took": 2,
"timed_out": false,
"total": 0,
"updated": 0,
"deleted": 0,
"batches": 0,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1,
"throttled_until_millis": 0,
"failures": []
}
Run Code Online (Sandbox Code Playgroud)
检查:if(response.updated == 0) 像这样。True => 安全插入新对象。(同时检查是否有冲突)
POST /test/type/
{
"text": "some text",
"type": "a real type",
"occurences": 1
}
Run Code Online (Sandbox Code Playgroud)
否则什么也不做,并且您的出现次数已更新。
使用此解决方案,您可能会遇到竞争条件,并且您将得到 version_conflicts。如果您遇到此问题,您可以做 3 件事。
使用这些选项:
waitForCompletion:true,冲突:“继续”,刷新:true
这将导致请求挂起,直到解决为止,因此响应时间会更长,并且它将等待完成并阻塞。每次索引后刷新也是非常糟糕的做法,因为它会重新索引您的数据。这将导致版本更新,并且您将不再有版本冲突。
| 归档时间: |
|
| 查看次数: |
4813 次 |
| 最近记录: |