es分页三种方式比较

(1) from / size : 该查询的实现原理类似于mysql中的limit,比如查询第10001条数据,那么需要将前面的10000条都拿出来,进行过滤,最终才得到数据。(性能较差,实现简单,适用于少量数据,数据量不超过10w)。
(2) scroll:该查询实现类似于消息消费的机制,首次查询的时候会在内存中保存一个历史快照以及游标(scroll_id),记录当前消息查询的终止位置,下次查询的时候将基于游标进行消费(性能良好,维护成本高,在游标失效前,不会更新数据,不够灵活,一旦游标创建size就不可改变,适用于大量数据导出或者索引重建)
(3) search_after: 性能优秀,类似于优化后的分页查询,历史条件过滤掉数据。

scroll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#scroll深度分页
result = es.search(index=['patent_cn_v71'],body=
{
'query':{
'match_all':{}
},
'sort':{
'app_text':'asc'
}
},scroll='1m',size=10000)
mdata = result.get("hits").get("hits")
scroll_id = result["_scroll_id"]
total = result["hits"]["total"]
j = 1
for i in range(total//10):
res = es.scroll(scroll_id=scroll_id, scroll='1m') #scroll参数必须指定否则会报错
mdata += res["hits"]["hits"]
break
for result in mdata:
print(result['_source']['app_text'])

search_after

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from elasticsearch import Elasticsearch

es = Elasticsearch(hosts={

'192.168.0.220',

'192.168.0.225',

'192.168.0.221',

},

timeout=3600)
i = 5000
next_id = 0
while i == 5000:
result_2 = es.search(index=['patent_cn_v71'],

body={
"query": {
"match_all": {}
},
"sort": [
{"app_text": "asc"}
],
"search_after": [next_id],
},
filter_path=[
'hits.hits._source.ipcr_text',
'hits.hits._source.ipc_text',
'hits.hits._source.id',
'hits.hits._source.app_text',
],
size=5000,
)
try:
result_2 = result_2['hits']['hits']
except:
break
for result in result_2:
app_text = result['_source']['app_text']
i = len(result_2)

from size

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
i = 10
j = 0
while i == 10:
result = es.search(index=['patent_cn_v71'],body=
{
'query':{
'match_all':{}
},
'sort':[{
'app_text':'asc'
}],
'from':j,
'size':10
},
filter_path = ['hits.hits._source.app_text'],
)
j+=10
i = len(result['hits']['hits'])
print(result)