在ElasticSearch中实现分页查询的方式有两种,分别为深度分页(from-size)和快照分页(scroll)
-
快照分页(scroll)
相对于from和size的分页来说,使用scroll可以模拟一个传统数据的游标,记录当前读取的文档信息位置。这个分页的用法,不是为了实时查询数据,而是为了一次性查询大量的数据(甚至是全部的数据)。因为这个scroll相当于维护了一份当前索引段的快照信息,这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。但是它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d ' { "query": { "match" : { "title" : "elasticsearch" } } }
该查询会自动返回一个_scroll_id,通过这个id(经过base64编码)可以继续查询
curl -XGET '集群节点IP:9200/_search/scroll?scroll=1m&scroll_id=c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1'
-
python 实现
#coding: utf-8 from elasticsearch import Elasticsearch if __name__ == "__main__": hosts = 'localhost:9200/' es = Elasticsearch(hosts=hosts, maxsize=25) index_name = 'test_es' dbname='test_bj' tbl='test_table1' test_table = "%s.%s" % (dbname, tbl) query_json = {"match_all": {}} es_data=es.search(index=index_name, doc_type=dbname, body={"query": query_json},filter_path=["_scroll_id","hits.total","hits.hits._id"], scroll = '5m',size =1000,timeout='1s') es_ids = [ int(id['_id']) for id in es_data.get("hits").get("hits")] scroll_id = es_data['_scroll_id'] es_total = es_data.get('hits').get('total') for i in range(es_total/1000): res = es.scroll(scroll_id=scroll_id,scroll='5m') es_ids += [int(id['_id']) for id in res.get('hits').get('hits')] sql_not_exist = "SELECT id from " + test_table +" where id not in " + str(tuple(es_ids)) cur_sell.execute(sql_not_exist) print "es缺少数据"+str(cur_sell.fetchall())
参考:
https://blog.csdn.net/u013514928/article/details/78749419
http://www.cnblogs.com/blue163/p/8126156.html