我正在尝试使用 update_by_query 更新文档的嵌套类型字段。我正在使用以下脚本查询:
POST test/_update_by_query
{
"script": {
"source": "ctx._source.address = params.address",
"params": {
"address": [{"city":"Mumbai"}]
}
},
"query": {
"bool": {
"must": [
{
"term": {
"uid": "b123"
}
}
]
}
}
}
但是我收到以下错误:
version conflict, required seqNo [607], primary term [16]. current document has seqNo [608] and primary term [16]
此问题的原因是什么以及如何解决此问题?我可以在这里使用任何其他查询来代替 _update_by_query 吗?请在这里帮助我
按查询更新会获取数据快照,然后更新每个匹配的文档。此错误意味着在您通过查询调用更新开始运行后,该文档已被另一个进程更新...
您可以选择忽略这些冲突问题,方法如下:
POST test/_update_by_query?conflicts=proceed
在响应中,您将看到有多少文档存在冲突,如果需要,您可以再次通过查询运行更新以选取它们。
更新:
如果您只需要更新单个文档并且知道其 ID,那么您不需要使用查询更新,而只需使用 更新端点。最大的优点是更新端点有一个名为
retry_on_conflict
的参数,它将在发生冲突时重试操作,这样您就可以确保在调用返回时文档最终被更新:
POST test/_doc/123/_update?retry_on_conflict=3
{
"doc": {
"address": [{"city":"Mumbai"}]
}
}
您可以在查询的参数中使用
refresh=True
。
我遇到了同样的问题,需要使用刷新 = true 在同一索引上依次执行两个查询解决了我的问题
await elasticWrapper.client.updateByQuery({
index: ElasticIndex.Customer,
refresh: true,
body: {
query: {
bool: {
must: [
{
match: {
'user.id': id,
},
},
],
},
},
script: {
source: `ctx._source.user=params.user`,
lang: 'painless',
params: {
user: { id, name: fullName, thumbnail },
},
},
},
});
await elasticWrapper.client.updateByQuery({
index: ElasticIndex.Customer,
refresh: true,
body: {
query: {
nested: {
path: 'tasks',
query: {
bool: {
must: [
{
exists: {
field: 'tasks.assignee',
},
},
{
term: {
'tasks.assignee.id': id,
},
},
],
},
},
},
},
script: {
source: `for (int i = 0; i < ctx._source.tasks.size();i++){
if(ctx._source.tasks[i].assignee.id == params.id){
ctx._source.tasks[i].assignee.thumbnail = params.thumbnail
}
}`,
lang: 'painless',
params: {
id,
thumbnail,
},
},
},
});
}
我正在使用
CustomResource
中的 AWS CDK
在 OpenSearch
域上添加和更新角色。
一切的灵感都来自这里:描述请求签名的文档
我遇到了这个版本冲突问题,所以我从其他答案中实现了
refresh=true, retry_on_conflict=3
。这是我通过 CustomResource
发送的 python NodeJS lambda function
请求的样子:
from aws_cdk import custom_resources as cr
...
es_requests_provider = cr.Provider(
scope=self,
id="es_requests_provider",
on_event_handler=self.es_requests_func, # Lambda function that actually talks to the domain
)
modify_role = CustomResource(
scope=self,
id="es_requests_resource_modifyRole",
service_token=es_requests_provider.service_token,
properties={
"requests": [
{
"method": "PUT",
"retry_on_conflict": "3",
"refresh": "true",
"path": f"_opendistro/_security/api/rolesmapping/lambda_write_access",
"body": {
"backend_roles": [
addToSearch_lambda.role.role_arn, # I'm adding a role for another lambda function to add stuff to the domain
],
"hosts": [],
"users": [],
},
},
]
},
)
希望这对某人有帮助。