0%

分页查询

分页查询

之前在基本操作中说过分页查询使用from+size来进行查询,对于数据量不大的可以这么用,但是对于数据量大的深度分页这样会造成性能问题

from+size分页查询

size是返回的条数,from是跳过的条数

1
GET _search?size=20&from=100

或者使用dsl请求

1
2
3
4
5
6
GET _search

{
"size":20,
"from":100
}

这里是需要去每个分片去进行查询的,假如设置from为100,size为20,此时每个分片都需要先取出from+size=120条数据,然后将各分片数据聚合之后在进行一次全局排序,获取出120条数据,在从第100条开始,往后选20条数据。

如果翻页过深的话,需要从各分片筛选出大量的数据,那如何解决深度分页的问题呢?可以使用scroll游标

scroll分页

使用scroll每次获取一页的数据,并且会带有一个_scroll_id,根据这个_scroll_id去不断的获取下一页的数据

1
2
3
4
5
6
7
// scroll=1m表示该scroll_id一分钟内可用
GET _search?scroll=1m

{
"size":20,
"from":100
}

此时会返回一个_scroll_id,向下翻页的时候就不需要使用索引了,而是使用_search/scroll来进行查询

1
2
3
4
5
6
7
GET _search/scroll

// scroll_id是上个请求返回的_scroll_id
{
"scroll_id": "FGluY2x1ZGVfY29udGV4dF91dWlkDnF1ZXJ5VGhlbkZldGNoBRZPemtZMGllb1FqdVhicjF5cTNybjJRAAAAAAAAC7EWS3N6ejk0LXdSR3FyXzlGb0VuQ3hrZxZPemtZMGllb1FqdVhicjF5cTNybjJRAAAAAAAAC7IWS3N6ejk0LXdSR3FyXzlGb0VuQ3hrZxZPemtZMGllb1FqdVhicjF5cTNybjJRAAAAAAAAC7MWS3N6ejk0LXdSR3FyXzlGb0VuQ3hrZxZPemtZMGllb1FqdVhicjF5cTNybjJRAAAAAAAAC7QWS3N6ejk0LXdSR3FyXzlGb0VuQ3hrZxZPemtZMGllb1FqdVhicjF5cTNybjJRAAAAAAAAC7UWS3N6ejk0LXdSR3FyXzlGb0VuQ3hrZw==",
"scroll":"1m"
}

可以看到这种方法只能一页一页的看,不能进行跳页。而且会占用大量资源,因为scroll的原理是做数据快照

search_after分页

search_after是根据上一页的最后一条数据来确定下一页的位置,也无法进行跳页请求

1
2
3
4
5
6
7
8
9
10
11
12
13
GET _search

{
"from": 0,
"size": 5,
"sort": [
{
"_id": {
"order": "desc"
}
}
]
}

这里需要带着sort才会返回对应的sort属性,每个对象中会返回一个

1
2
3
"sort": [
"AuvQEIoBP0MzcZD49Ihs"
]

之后拿着最后一条数据的sort,来进行查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
GET _search

{
"from": 0,
"size": 5,
"search_after": [
"AuvQEIoBP0MzcZD49Ihs"
],
"sort": [
{
"_id": {
"order": "desc"
}
}
]
}

欢迎关注我的其它发布渠道