elastic search在普通方式查询时会返回记录总数以及开头的若干条,即便指定from和相应的长度size也有总数限制。根据文档介绍,这时需要通过scroll分页查询,在初次查询时指定改方式,之后不断的调用scroll方法针对同_scroll_id会得到后续数据。就像通过一个固定的游标以及指定的窗口大小来不断滚动获得新的数据。
from elasticsearch import Elasticsearch
if __name__ == '__main__':
es =elasticSearch('elk.dev')
page = es.search(index='prod_nginx_20170211', _source=['localtime', 'request'], scroll='2m', size=10)
sid = page['_scroll_id']
page_size = page['hits']['total']
for i in range(page_size//10 + 1):
res = es.scroll(scroll_id = sid)
for doc in res['hits']['hits']:
print(doc['_source']['localtime'] + '---->' + doc['_source']['request'])
print("===================================\n")
结果:
脚本执行总是在刷出30条记录后报错。”elasticsearch.exceptions.NotFoundError: TransportError(404, ‘search_phase_execution_exception’, ‘No search context found for id [874876]’)”
pub单步调试时,也是在30条后,再次执行res = es.scroll(scroll_id=sid)时报404错误。(未解)
curl方式测试对比
在群里以及文档中介绍的提示,scroll查询时也可能会改变scroll_id值,所以每次查询时需要使用最新的scroll_id。但测试发现从elasticsearch.scroll方法返回的结果中并没有scroll_id值。
换另一种调用方式,在kibana中直接GET:
## 先初次查询指定scroll
GET /prod_nginx_20170211/_search?scroll=1m&size=100
{
"_source": ["localtime", "request"]
}
## 调用scroll
GET /_search/scroll
{
"scroll": "1m",
"scroll_id": "DnF1ZXJ5VGhlbkZldGNoAwAAAAAADaFSFlh6SG0xQmYxU2JXNm1sLXRZNFFCZ1EAAAAAAA2hVBZYekhtMUJmMVNiVzZtbC10WTRRQmdRAAAAAAANoVMWWHpIbTFCZjFTYlc2bWwtdFk0UUJnUQ=="
}
## 后续查询时,使用返回结果中最新的scroll_id更新上面的再次查询
(PS:20170213)