大数跨境
0
0

别再用错 OpenSearch 分页!From-Size/Scroll/Search After 全解析

别再用错 OpenSearch 分页!From-Size/Scroll/Search After 全解析 Tina讲出海
2025-10-14
5
导读:别再用错 OpenSearch 分页!From-Size/Scroll/Search After 全解析

OpenSearch

不同分页查询的接口使用

分页查询大概分为3个。

  1. from   size

  2. search_after

  3. scroll search

在日志/指标/全文检索的世界里,数据量往往巨大。如何高效、安全地翻页获取结果,是每个开发/运维都必须掌握的技能。本文用最少的理论、最多的实战,带你掌握 OpenSearch(Elasticsearch 兼容)中三大分页套路,告诉你什么时候用哪种、怎么写、哪些坑不能踩——读完就能上手实战。





方式
优点
缺点
适用场景
from + size
简单直观、适合 UI 翻页
深度翻页性能差、有 max_result_window 限制(默认 10000)
简单分页(页数小、数据量有限)
search_after
性能优,适合深度分页,不受 from 限制
需要稳定排序字段(比如 @timestamp + _id),必须用上一次最后一条的 sort 值
大量分页、按时间/唯一键顺序遍历
scroll
高效批量遍历、快照一致性
占用服务端资源(有生命周期),非实时场景更合适
批量导出、重建索引、离线处理


01
from+size (页数通常 < 100,数据量不是太大)


GET my-index/_search

{

  "from": 0,

  "size": 20,

  "query": { "match_all": {} },

  "sort": [{ "@timestamp": "desc" }]

}


注意

  • from+size<=index.max_result_window(默认 10000)。深度翻页会触发 Result window is too large 错误。

  • from 越大性能越差,因为底层需要跳过大量文档。


02
search_after(深度分页首选)

第一次查询:

GET my-index/_search

{

  "size": 100,

  "query": { "match_all": {} },

  "sort": [

    { "@timestamp": "asc" },

    { "_id": "asc" }

  ]

}

第二次查询:

GET my-index/_search

{

  "size": 100,

  "query": { "match_all": {} },

  "sort": [

    { "@timestamp": "asc" },

    { "_id": "asc" }

  ],

  "search_after": [1697000000000, "abc123"]

}

注意:

search_after 需要客户端保存上页最后一条的 sort 值。

若排序字段在索引中类型不一致(多索引查询),会报错——确保 mapping 一致。

search_after 不受 max_result_window 限制。


03
导出/批量读取:scroll(快照式遍历)

第一次请求:开启快照(例如 scroll=5m)并返回第一批数据与 _scroll_id

后续请求:使用 _search/scroll POST body 提交 scroll_id 和 scroll 值获取下一批。

第一次查询:

GET my-index/_search?scroll=1m

{

  "size": 100,

  "query": { "match_all": {} },

  "sort": [

    { "@timestamp": "asc" },

    { "_id": "asc" }

  ]

}

GET/_search/scroll

{
  "scroll": "1m",
  "scroll_id": ""
}





共筑美好家园




END







【声明】内容源于网络
0
0
Tina讲出海
跨境分享间 | 每日提供跨境资讯
内容 47307
粉丝 1
Tina讲出海 跨境分享间 | 每日提供跨境资讯
总阅读222.4k
粉丝1
内容47.3k