使用Python DSL Elasticsearch UpdateByQuery单独更新大量文档

时间:2019-07-10 16:34:55

标签: elasticsearch elasticsearch-dsl elasticsearch-dsl-py

我正在尝试使用UpdateByQuery来更新大量文档的属性。但是由于每个文档都有不同的值,因此我需要一个一个地执行。我正在遍历大量文档,对于每个文档,我称其为funcion:

def update_references(self, query, script_source):

    try:
        ubq = UpdateByQuery(using=self.client, index=self.index).update_from_dict(query).script(source=script_source)
        ubq.execute()

    except Exception as err:
        return False

    return True

一些示例值是:

  • query = {'query':{'match':{'_id':'VpKI1msBNuDimFsyxxm4'}}}
  • script_source ='ctx._source.refs = [\'python \',\'java \']'

问题是当我这样做时,出现一个错误:“其中的动态脚本编译太多,最大值:[75 / 5m];请使用索引或带有参数的脚本代替;此限制可以由[script.max_compilations_rate]设置”。

如果我使用Kibana更改max_compilations_rate,则无效:

PUT _cluster/settings
{
  "transient": {
    "script.max_compilations_rate": "1500/1m"
  }
}

无论如何,最好使用参数化脚本。我尝试过:

def update_references(自身,查询,script_source,script_params):

    try:
        ubq = UpdateByQuery(using=self.client, index=self.index).update_from_dict(query).script(source=script_source, params=script_params)
        ubq.execute()

    except Exception as err:
        return False

    return True

所以这次:

  • script_source ='ctx._source.refs = params.value'
  • script_params = {'value':[\'python \',\'java \']}

但是由于每次都必须更新查询和参数,因此我需要为大型集合中的每个文档创建一个新的UpdateByQuery实例,结果是相同的错误。

我还尝试遍历并使用以下内容更新大集合:

es.update(
    index=kwargs["index"],
    doc_type="paper",
    id=paper["_id"],
    body={"doc": {
        "refs": paper["refs"]  # e.g. [\\'python\\', \\'java\\']
    }}
)

但是出现以下错误:“无法建立新的连接:[Errno 99]无法分配请求的地址juil。10 18:07:14围兜gunicorn [20891]:POST http://localhost:9200/papers/paper/OZKI1msBNuDimFsy0SM9/_update [状态:N / A request:0.005s“

因此,如果您对如何解决此问题有任何想法,将不胜感激。 最好,

0 个答案:

没有答案