python elasticsearch bulk_关于ElasticSearch Bulk的用法

本文介绍了如何使用Elasticsearch的Python API进行批量数据处理。针对千万级别的数据,作者通过bulk() API实现了从多个Index中筛选数据并导入新Index,以及在现有Index中批量更新数据并添加新field的操作。在解决过程中,作者遇到并解决了_actions参数的理解问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Background

刚接触ElasticSearch不久,公司让我帮忙去导一下数据,刚开始数量并不是很大,我都是用Elasticsearch python的api接口,一条一条数据去往新的index里插. 但是马上又有了千万级别的数据需要操作,如果还是老办法,会特别慢,而且不够稳定。于是去查了一下资料。关于Elasticsearch的python api文档很少,中文的就更少了,官方稳定又不是很详细,只是大概得到一个信息,可以用bulk() api去操作大量的数据。

Solution:

我需要解决的问题有两个:

查询多个Index中的内容,然后将满足条件的数据写到新的一个Index中:

这个问题比较简单,elasticsearch 的helpers module提供了一个完美的方法来做这件事:reindex()

elasticsearch.helpers.reindex(client, source_index, target_index, query=None,target_client=None, chunk_size=500, scroll=u'5m', scan_kwargs={}, bulk_kwargs={})

这个方法的参数,提供了source_index(可以是List), target_index, query以及 scroll_size 和 scroll的保存时间,所以直接跑就可以了。

批量更新现有Index中的所有数据,给每个document增加一个field并赋值:

官方文档中的api 签名是这样的:

elasticsearch.helpers.bulk(client, actions, stats_only=False, **kwargs)

我一直没搞明白actions是什么类型的参数,以为是个函数类行的参数,后来看了一下源码,发现其实是一个List, 而且是要被操作的document的集合,官方文档上显示是要满足这个样子,跟search()返回的结果格式一样:

{ '_index': 'index-name', '_type': 'document', '_id': 42, '_parent': 5, '_ttl': '1d', '_source': { "title": "Hello World!", "body": "..." }}

但是又说:The bulk() api accepts index, create, delete, and update actions. Use the _op_type field to specify an action (_op_type defaults to index):

{ '_op_type': 'delete', '_index': 'index-name', '_type': 'document', '_id': 42,}{ '_op_type': 'update', '_index': 'index-name', '_type': 'document', '_id': 42, 'doc': {'question': 'The life, universe and everything.'}}

我在自己的数据上加了"_op_type":"update", 然后运行一直出错:

TransportError(400, u'action_request_validation_exception',u'Validation Failed: 1: script or doc is missing

直到我尝试着删掉"_op_type"这个字段,终于运行成功了。以下是我的代码:

def queryInES( esinstance):

search_body={"query":{"match_all":{}}}

page = esinstance.search(index='my_index', body=search_body, search_type='scan', doc_type='Tweet', scroll='5s', size=1000)

sid=page['_scroll_id']

scroll_size = page['hits']['hits']

while(scroll_size>0):

pg = es.scroll(scroll_id=sid, scroll='30s')

scroll_size = len(pg['hits']['hits'])

print "scroll size: " + str(scroll_size)

sid = pg['_scroll_id']

data=pg['hits']['hits']

... ...

for i in range(0, scroll_size):

data[i]['_source']['attributes']['senti']={"label":label, "score": score, "confidence": confidence}

helpers.bulk(client=esinstance, actions=data)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值