【ElasticSearch】看懂Search After怎么分页
深度分页是什么
-
普通的分页方式是,通过**from(从哪条数据开始查) 和 size(查几条)**直接分页
-
先了解一下elasticsearch的数据存储方式
- elasticsearch的数据一般会采用分片存储,也就是把一个索引中的数据分成N份,存储到不同节点上,而且分片并不是按顺序分片的(不能直接根据分片顺序来分页)
-
引入一个场景:比如一个索引库中有 100000 条数据,分别存储到4个分片,每个分片25000条数据。现在每页查询10条,查询第99页。那么分页查询的条件如下:
GET /items/_search { "from": 990, // 从第990条开始查询 "size": 10, // 每页查询10条 "sort": [ { "price": "asc" } ] }从语句来分析,要查询第990~1000名的数据。
从实现思路来分析,肯定是将所有数据排序,找出前1000名,截取其中的990~1000的部分。但问题来了,我们如何才能找到所有数据中的前1000名呢?
要知道每一片的数据都不一样,第1片上的第900-1000,在另1个节点上并不一定依然是900-1000名。所以我们只能在每一个分片上都找出排名前1000的数据,然后汇总到一起,重新排序(把每一个分片的前1000名汇总),才能找出整个索引库中真正的前1000名,此时截取990~1000的数据即可。
-
假如我们现在要查询的是第999页数据呢,是不是要找第9990~10000的数据,那岂不是需要把每个分片中的前10000名数据都查询出来,汇总在一起,在内存中排序?如果查询的分页深度更深呢,需要一次检索的数据岂不是更多?
由此可知,当查询分页深度较大时,汇总数据过多,对内存和CPU会产生非常大的压力。
因此elasticsearch会禁止
from+ size超过10000的请求。 -
针对深度分页,elasticsearch提供了两种解决方案:
search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。scroll:原理将排序后的文档id形成快照,保存下来,基于快照做分页。官方已经不推荐使用。
[!IMPORTANT]
Search After 的核心思想
Search After 不是一个“跳转到任意页面”的解决方案,而是一个“无限滚动”或“连续浏览”的解决方案。
- aftersearch得到第一页的方式和普通的分页一样,后面的分页多了一个筛选条件,即上一页最后一个数据的信息
- 对于上述场景如,要得到第99页(每页10条文档)的10调文档
- 普通分页:每个分片拿出自己的前1000条数据,随后进行组合,再进行排序(在内存中进行),再挑出 991-1000条数据,得到每一页都是如此,每一次分页的压力都很大
- search after(缺点是不能跳到别的页):
- 得到第一页的方式与普通分页方式相同(每个分片拿出自己的前10条数据,随后进行组合,再进行排序(在内存中进行),再挑出 1-10条数据),记录下第一页的页尾信息
- 接下来要得到第二页时,每一个分片都选出在第一页 页尾 后的 10条数据,随后进行组合,再进行排序(在内存中进行),再挑出 1-10条数据,记录下第二页的页尾信息,这样每次分页的成本不高。
如果顺序翻页,速度很快。
但是不支持跳跃翻页,比如从第1页直接跳到100页
总结:
大多数情况下,我们采用普通分页就可以了。查看百度、京东等网站,会发现其分页都有限制。例如百度最多支持77页,每页不足20条。京东最多100页,每页最多60条。基本上没人看这么多页
因此,一般我们采用限制分页深度的方式即可,无需实现深度分页。
616

被折叠的 条评论
为什么被折叠?



