通过查询更新
The Update By Query
对象
The Update By Query
对象允许使用 _update_by_query 端点对匹配搜索查询的文档执行更新。
该对象实现为 Search
对象的修改,包含其查询方法的子集,以及一个脚本方法,用于进行更新。
The Update By Query
对象实现了以下 Search
查询类型
查询
过滤器
排除
有关查询的更多信息,请参阅 Search DSL 章节。
与 Search
对象一样,API 设计为可链接的。这意味着 Update By Query
对象是不可变的:对该对象的所有更改都将导致创建包含更改的浅拷贝。这意味着您可以安全地将 Update By Query
对象传递给外部代码,而不必担心它会修改您的对象,只要它坚持使用 Update By Query
对象 API。
您可以通过多种方式定义您的客户端,但首选方法是使用全局配置。有关定义客户端的更多信息,请参阅 Configuration 章节。
定义完客户端后,您可以如下所示实例化 Update By Query
对象的副本
from elasticsearch_dsl import UpdateByQuery
ubq = UpdateByQuery().using(client)
# or
ubq = UpdateByQuery(using=client)
注意
所有方法都返回对象的副本,使其可以安全地传递给外部代码。
API 是可链接的,允许您在一个语句中组合多个方法调用
ubq = UpdateByQuery().using(client).query("match", title="python")
要将请求发送到 Elasticsearch
response = ubq.execute()
需要注意的是,使用脚本方法进行链接存在限制:多次调用脚本将覆盖先前值。也就是说,一次调用只能发送一个脚本。尝试使用两个脚本将导致仅存储第二个脚本。
鉴于以下示例
ubq = UpdateByQuery().using(client).script(source="ctx._source.likes++").script(source="ctx._source.likes+=2")
这意味着此客户端存储的脚本将是 'source': 'ctx._source.likes+=2'
,而之前的调用将不会被存储。
为了调试目的,您可以将 Update By Query
对象显式序列化为 dict
print(ubq.to_dict())
此外,要在脚本中使用变量,请参见以下示例
ubq.script(
source="ctx._source.messages.removeIf(x -> x.somefield == params.some_var)",
params={
'some_var': 'some_string_val'
}
)
序列化和反序列化
搜索对象可以使用 .to_dict()
方法序列化为字典。
您还可以使用 from_dict
类方法从 dict
创建 Update By Query
对象。这将创建一个新的 Update By Query
对象,并使用字典中的数据对其进行填充
ubq = UpdateByQuery.from_dict({"query": {"match": {"title": "python"}}})
如果您希望修改现有的 Update By Query
对象,覆盖其属性,请改用 update_from_dict
方法,该方法会就地更改实例
ubq = UpdateByQuery(index='i')
ubq.update_from_dict({"query": {"match": {"title": "python"}}, "size": 42})
额外属性和参数
要设置搜索请求的额外属性,请使用 .extra()
方法。这可用于定义无法通过特定 API 方法(如 explain
)定义的主体中的键
ubq = ubq.extra(explain=True)
要设置查询参数,请使用 .params()
方法
ubq = ubq.params(routing="42")
响应
您可以通过调用 .execute()
方法来执行搜索,该方法将返回一个 Response
对象。The Response
对象允许您通过属性访问访问响应字典中的任何键。它还提供了一些方便的帮助程序
response = ubq.execute()
print(response.success())
# True
print(response.took)
# 12
如果您想检查 response
对象的内容,只需使用其 to_dict
方法即可获取原始数据以进行漂亮打印。