- 通过id直接update
Elasticsearch 中的 update API 支持根据用户提供的脚本去实现更新
Update 更新操作允许 ES 获得某个指定的文档,可以通过脚本等操作对该文档进行更新。
可以把它看成是先删除再索引的原子操作,只是省略了返回的过程,这样即节省了来回传输的网络流量,也避免了中间时间造成的文档修改冲突。
注意 body 参数,我们需要添加 doc 或者 script 变量来指定修改的内容
from elasticsearch_dsl import connections
from elasticsearch_dsl import Search,Q
conn = connections.create_connection(hosts=['192.168.214.131'],port=9200, http_auth="elastic:ellischen")
conn.update(index='books',id='lO2DhoIB-l1diKmt8NnZ', body={"doc": {"title": "Jerry"}})
增加字段
es.update(index="test", doc_type="doc", id="4Z6XcXcBChYTHL1ZdwjL", body={"doc": {"name": "Jerry", "age": 25}})
- query update
update_by_query,顾名思义,这种更新方式,即通过查询再更新。
该方法的优点是可以指定某些数据,然后达到更新的目的
在 ES 中,我们通过 update_by_query 中的 query 和 script 来实现先查询再更新的机制
import re
from elasticsearch_dsl import connections
from elasticsearch_dsl import Search,Q
conn = connections.create_connection(hosts=['192.168.214.131'],port=9200, http_auth="elastic:ellischen")
data = {"title":"ellis"}
script = f"ctx._source.title = {data.get('title',None)}"
update_body = {
"query": {
"ids": {
"values": ["lO2DhoIB-l1diKmt8NnZ"]
}
},
"script": {
"inline": "ctx._source.title = params.title",
"params":{
"title":"gggggg"
},
"lang":"painless"
}
}
conn.update_by_query(index='books', body=update_body)
在上面的操作中:query 字段,表示我们要查询的条件,根据该条件找到对应的数据 script 字段包含以下关键字:
source 是将要执行的脚本内容;
lang 表示的是当前脚本的语言*;
param 则是脚本执行的参数;
3. 批量更新
在实际需求中,面对最多的还是批量更新
当然你也可以通过 for 循环一条一条来更新,不过这种方法效率太低了。
尤其是面对数据量很大的时候,那真的是急死人…
好在 ES 有提供批量操作的接口 bulk
在 Python 中可以直接导入使用
from elasticsearch.helpers import bulk
那么在 bulk 中如何使用 update 呢?请看代码
actions = []
for item in data_list:
_id = item.get("_id")
doc = item.get("doc")
index_action = {
'_op_type': 'update',
'_index': index_name,
'_type': "doc",
'_id': _id,
'doc': doc
}
actions.append(index_action)
if actions:
bulk(es, actions)
可以看到有个 doc 的参数,和上面介绍的 update 方法类似,doc中的值便是我们需要修改的字段内容
_op_type 为操作类型为update,表明是更新的操作
以该种方式组合的 index_action 组成数组,通过 bulk 便能实现批量更新 !
以上便是通过 Python 更新 Elasticsearch 的几种方法