`elasticsearch` 在使用 from + size 这种方式进行分页查询时,因为 `index.max_result_window` 的默认值是 10K,所以当查询的文档超过第10K个文档时,会报错:Result window is too large...
当然,我们可以调整`index.max_result_window`的大小,不过这种办法会导致查询效率降低和内存占用增加。

本文讲述了在 `elasticsearch` 中包含几十万乃至上百万的大数据量时,使用 `search_after` 进行深度分页的方法。

 

如何使用 search_after

1. 准备工作:确定可以唯一确定一条文档的键,类似于关系数据库的主键,用它来排序稳定且唯一。
比如:这个逐渐字段是 `lawId`,当然,也可以使用多个字段联合作为主键:

"sort": [
  {"lawId": "asc"}
]

 

2. 首次查询:指定排序规则:

GET /my_index/_search
{
  "size": 10,
  "sort": [
    {"lawId": "asc"}
  ],
  "query": {
    "match_all": {}
  }
}

 

 

3. 后续查询:将第一次查询结果的最后一条记录的 sort 值作为 `search_after` 的参数:

GET /my_index/_search
{
  "size": 10,
  "sort": [
    {"lawId": "asc"}
  ],
  "search_after": [1680207200000],
  "query": {
    "match_all": {}
  }
}

  

代码实现

您可以点击以下链接下载源代码:

- [github]
- [gitee]
- [gitcode]


总结

经过实际测试,在对几万文档分页时,速度挺快的;对几十万量级文档进行分页时,还是比较慢;因为skip次数多也比较消耗时间。
如果文档量达到百万计,要从操作使用方面着手进行设计,避免深度分页时skip太多次。


🪐祝好运🪐