首页/数据/NoSQL 速查/sort 排序与 from/size 分页
Elasticsearch89 条

sort 排序与 from/size 分页

搜索默认按 _score 相关度排序,也可指定字段排序(支持 order、missing、mode);from+size 分页受 index.max_result_window 限制,默认最多取到一万条。

NoSQL 速查数据更新于 2026-10-13

排序与分页是什么

搜索默认按 _score 相关度排序,也可以指定字段排序并控制 order、missing 与数组字段的 mode。分页用 from 加 size,受 index.max_result_window 限制(默认最多取到一万条)。深分页要改用 search_after 配合稳定排序键,否则每次都要跳过前面所有文档,代价随页数线性上升。

基本信息

排序写法"sort": [ { "date": "desc" }, "_score" ]
字段排序限制text 字段不能直接排序,要用 keyword 子字段
分页上限from + size 不超过 index.max_result_window,默认 10000
深分页方案search_after + 唯一稳定的排序键
总数统计track_total_hits 控制是否精确统计命中总数
适用版本Elasticsearch 7.x / 8.x

典型使用场景

  • 商品列表按价格、销量或上架时间排序
  • 日志按时间倒序查看最新事件
  • 列表页常规分页,页数不深的场景用 from 加 size
  • 导出大数据量结果集,用 search_after 逐批拉取
  • 需要精确总数时开启 track_total_hits
  • 多级排序:主键相同再按时间或 ID 兜底排序

示例

示例
GET /my-index/_search
{
  "from": 20,
  "size": 10,
  "sort": [
    { "publish_date": { "order": "desc", "missing": "_last" } },
    { "_score": "desc" }
  ],
  "track_total_hits": true
}

GET /my-index/_search
{
  "size": 10,
  "sort": [ { "publish_date": "desc" }, { "_id": "asc" } ],
  "search_after": [ 1750000000000, "doc-9" ]        # 深分页续取
}

排序参数读法

参数作用注意点
orderasc / desc多字段分别指定
missing_last / _first缺失值位置
modemin/max/avg/sum/median数组字段取哪个元素
unmapped_type未映射字段类型避免查询报错
track_total_hits是否精确统计总数默认只统计到一万
search_after从上次结果之后取排序键必须唯一稳定

排序与分页实践

  • 排序字段要建索引,否则只能现场计算或加载列存
  • 排序键加 _id 兜底,避免相同值时顺序不确定导致漏数据
  • 深分页一律改用 search_after,不要靠不断加大 from
  • 导出用滚动查询或 search_after,并控制每批大小
  • 对 text 字段排序前先确认有 keyword 子字段
  • 排序方向要与字段的 doc_values 用法一致,避免额外内存排序
track_total_hits 默认只统计到 10000 就返回 gte,需要精确总数时显式设为 true;只关心是否有结果时保持默认即可省开销。
from 加 size 超过 max_result_window 会直接报错,调大窗口只是绕过限制,真正的解决方式是改用 search_after。
数组字段排序默认取最小值(min 模式),需要别的语义必须显式设置 mode;单值字段不需要关注该参数。
search_after 依赖的排序键组合必须唯一且稳定,通常用「时间加 _id」,只按时间排序在时间相同时可能漏掉或重复文档。

深分页方案对比

  • from 加 size:最简单,页数一深性能迅速下降
  • scroll:适合一次性导出全量,会占用快照资源
  • search_after:适合用户侧深分页,需要稳定唯一排序键
  • 游标查询:适合实时性要求不高的滚动遍历
  • 导出任务优先 search_after 或 scroll,并控制每批大小
  • 调大 max_result_window 只是放开限制,解决不了性能问题

排序常见问题

  • 排序字段是 text 会直接报错,需要 keyword 子字段
  • 缺失值位置用 missing 指定,默认位置与预期不一定一致
  • 数组字段排序要明确 mode,否则默认取最小值
  • 多字段排序时后面的字段只在前面字段相同时才起作用
  • 把 _score 与字段混排要注意两者量纲不同
  • 排序键不唯一会导致分页结果重复或遗漏
分页总数返回 relation 为 gte 说明未精确统计;需要精确总数时把 track_total_hits 设为 true,代价是要遍历更多文档。
排序依赖字段的正排数据(doc_values),它默认开启;关闭了 doc_values 的字段无法排序,只能重新映射或改用运行时字段计算排序值。

分页参数速记

  • from 默认 0、size 默认 10,取全量时要显式放大但仍受窗口限制
  • 排序字段与查询条件字段尽量复用同一个索引,减少内存排序
  • 导出场景不需要精确总数,把 track_total_hits 关掉可省一次统计
  • search_after 的排序键要能唯一定位文档,否则会重复或漏取

易错点

  • 文本字段不能直接排序,必须使用 keyword 子字段,否则会直接报错
  • from 加 size 超过默认一万的上限会报错,深分页应改用 search_after
  • 排序键不唯一时分页结果可能重复或遗漏,需要加唯一字段兜底
  • 对数组字段排序不注意 mode 会取到最小值,业务语义可能与预期不符
  • 只调大 max_result_window 而不改查询方式,深分页依然会越来越慢

数据来源与参考

  • Elasticsearch Guide: Sort search results
  • Elasticsearch Guide: Paginate search results
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌