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