即使使用 update_by_query 顺序更新文档,Elastic Search 也会出现版本冲突

问题描述 投票:0回答:4

我正在尝试使用 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 吗?请在这里帮助我

elasticsearch kibana elastic-stack elasticsearch-5
4个回答
8
投票

按查询更新会获取数据快照,然后更新每个匹配的文档。此错误意味着在您通过查询调用更新开始运行后,该文档已被另一个进程更新...

您可以选择忽略这些冲突问题,方法如下:

POST test/_update_by_query?conflicts=proceed

在响应中,您将看到有多少文档存在冲突,如果需要,您可以再次通过查询运行更新以选取它们。

更新:

如果您只需要更新单个文档并且知道其 ID,那么您不需要使用查询更新,而只需使用 更新端点。最大的优点是更新端点有一个名为

retry_on_conflict
的参数,它将在发生冲突时重试操作,这样您就可以确保在调用返回时文档最终被更新:

POST test/_doc/123/_update?retry_on_conflict=3
{
  "doc": {
    "address": [{"city":"Mumbai"}]
  }
}

5
投票

您可以在查询的参数中使用

refresh=True


2
投票

我遇到了同样的问题,需要使用刷新 = true 在同一索引上依次执行两个查询解决了我的问题

https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/update_by_query_examples.html

        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,
              },
            },
          },
        });
      }

0
投票

我正在使用

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": [],
                },
            },
        ]
    },
)

希望这对某人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.