ES 分页查询的几种方式对比

289 阅读3分钟

ES 分页查询

1、from + size:内存分页

基本用法

这和 SQL 的 limit 类似:

  • from:默认值是 0,代表当前页返回数据的起始值。
  • size:默认值是 10,代表当前页返回数据的条数。
GET /{index_name}/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ],
  "from": 10,
  "size": 10
}

基本原理

GET kibana_sample_data_flights/_search

{ "from": 10001, "size": 10 }

这会将 10011 条数据加载到内存,然后经过后台处理后返回了最后 10 条我们想要的数据。

优点

支持随机翻页。

缺点

  • 受制于 max_result_window 设置,不能无限制翻页。
  • 存在深度翻页问题,越往后翻页越慢。

max_result_window 默认值是 10000。也就意味着:如果每页有 10 条数据,会最大翻页至 1000 页。

应用场景

第一:适合小型数据集的业务场景。

第二:搜索引擎如谷歌支持随机跳转分页的业务场景。

2、Search After:向后翻页

使用前一页中的一组排序值来检索匹配的下一页。

前置条件:使用 search_after 要求后续的多个请求返回与第一次查询相同的排序结果序列。也就是说,即便在后续翻页的过程中,可能会有新数据写入等操作,但这些操作不会对原有结果集构成影响。

Search After 依赖于 PIT,我们与必要先了解一下 PIT。

PIT:时间点下的索引状态

Point In Time(PIT)是 Elasticsearch 7.10 版本之后才有的新特性,用于维护特定时间点的索引状态。

PIT 本质是存储索引数据状态的轻量级视图。

基本使用

1、创建 PIT

POST kibana_sample_data_logs/_pit?keep_alive=5m

keep_alive=5m,类似scroll的参数,代表视图保留时间是 5 分钟,超过 5 分钟执行会报错如下:

"type" : "search_context_missing_exception", "reason" : "No search context found for id [91600]"

2、查询

# Step 2: 创建基础查询
GET /_search
{
  "size":10,
  "query": {
    "match" : {
      "host" : "elastic"
    }
  },
  "pit": {
     "id":  "48myAwEXa2liYW5hX3NhbXBsZV9kYXRhX2xvZ3MWM2hGWXpxLXFSSGlfSmZIaXJWN0dxUQAWdG1TOWFMTF9UdTZHdVZDYmhoWUljZwAAAAAAAAEg5RZGOFJCMGVrZVNndTk3U1I0SG81V3R3AAEWM2hGWXpxLXFSSGlfSmZIaXJWN0dxUQAA", 
     "keep_alive": "1m"
  },
  "sort": [ 
    {"response.keyword": "asc"}
  ]
}

缺点

只支持向后翻页,不支持随机翻页。

3、Scroll:遍历全量数据

这类似 cursor 游标,就和 redis 禁止搜索全部数据,而必须用 cursor 一样

ES 同样禁止 match_all 的查询

基本使用

POST kibana_sample_data_logs/_search?scroll=3m 
{ "size": 100, "query": { "match": { "host": "elastic" } } }

返回一个 scroll_id,后续就可以通过 scroll_id 继续遍历数据

POST _search/scroll 
{ "scroll" : "3m", "scroll_id":"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkY4UkIwZWtlU2d1OTdTUjRIbzVXdHcAAAAAAAGmkBZ0bVM5YUxMX1R1Nkd1VkNiaGhZSWNn" }

隐式 PIT

在发出第一个 Scroll 请求时,类似在那一个时刻做了快照。随后对文档的更改(写入、更新或删除)只会影响以后的搜索请求。

缺点

非实时,数据量大的时候,响应时间可能会比较长。

小结

  • 1w条数据以内,随机跳转,用 from + size
  • 1w+数据,只会往后翻页,search_after,
  • 线上全量查询,scroll