elasticsearch-py使用scan和scroll返回所有文档
我正在使用 elasticsearch-py 来连接我的 Elasticsearch 数据库,这个数据库里有超过 300 万个文档。我想把所有的文档都提取出来,以便进行数据处理并写入 CSV 文件。我用下面的代码轻松地获取了 10 个文档(默认返回的数量)。
es=Elasticsearch("glycerin")
query={"query" : {"match_all" : {}}}
response= es.search(index="_all", doc_type="patent", body=query)
for hit in response["hits"]["hits"]:
print hit
不过,当我尝试使用扫描和滚动功能来获取所有文档时,遇到了一些问题。我尝试了两种不同的方法,但都没有成功。
方法一:
scanResp= es.search(index="_all", doc_type="patent", body=query, search_type="scan", scroll="10m")
scrollId= scanResp['_scroll_id']
response= es.scroll(scroll_id=scrollId, scroll= "10m")
print response
在
scroll/
后,它给出了滚动 ID,然后以 ?scroll=10m (Caused by <class 'httplib.BadStatusLine'>: ''))
结束。
方法二:
query={"query" : {"match_all" : {}}}
scanResp= helpers.scan(client= es, query=query, scroll= "10m", index="", doc_type="patent", timeout="10m")
for resp in scanResp:
print "Hiya"
如果在 for 循环之前打印出 scanResp,我得到的是 <generator object scan at 0x108723dc0>
。因此,我相对确定我在滚动过程中搞错了什么,但不太清楚具体是哪里出了问题,也不知道该怎么修复。
结果:

scroll/
后,它给出了滚动 ID,然后以 ?scroll=10m (Caused by <class 'httplib.BadStatusLine'>: ''))
结束。
我尝试增加传输类的最大重试次数,但这并没有改变什么。我非常希望能得到一些关于如何解决这个问题的建议。
注意:我的 Elasticsearch 在同一网络的远程桌面上。
2 个回答
2
你的问题解决了吗?
我有一个简单的解决办法,你每次调用滚动方法后,都必须更换一下 scroll_id
,像下面这样:
response_tmp = es.scroll(scroll_id=scrollId, scroll= "1m")
scrollId = response_tmp['_scroll_id']
11
Python中的scan方法会向REST API发送一个GET请求。它试图通过HTTP发送你的scroll_id。这里最可能的情况是,你的scroll_id太大,无法通过HTTP发送,所以你看到这个错误,因为没有返回任何响应。
由于scroll_id的大小是根据你拥有的分片数量而增长的,因此使用POST请求,并将scroll_id作为JSON的一部分发送会更好。这样可以避免因为太大而无法进行HTTP调用的问题。