【ES】深度分页
1. ES查询流程
ES的结构可以简化为协调节点(Coordination g Node),与数据节点(Data Node)。协调节点将请求转发给数据节点,数据节点返回满足条件的TopN文档信息(至少包含id,score)。协调节点从k*TopN的文档信息中选出最终的TopN的结果的id发送给数据节点。数据节点根据id查询数据,返回给协调节点。
ES分页的三种方式
2. from + size
ES对from+size有大小限制,默认值为10000。因此,不适合深度分页场景。因为查询[from,from+size)时,也会将[0,from)的结果也会查出来,导致CPU和内存的开销较大。
3. scroll
可以处理大量数据,不适合实时分页。scroll会在服务器维持一个查询上下文,占用系统资源。并且初始化scroll请求时,ES会创建一个当前搜索结果的快照。用户无法实时查看最新数据。
4. sort + search_after
search_after基于游标的分页方法。第一次搜索时,ES会返回第一页的结果。当需要获取下一页数据时,可以使用上一页最后一个文档的排序字段值作为游标进行搜索。
优势:
● 避免深度分页性能问题:与from+size相比,search_after不需要计算和存储大量中间结果,因此在深度分页时效率更高。
● 资源占用少:search_after只需要记录上一页最后一条数据的排序值,相比scroll机制需要维护大量数据上下文,占用的资源更少。
● 稳定的排序结果:search_after基于排序值定位下一页数据,保证即使数据更新,分页结果的顺序依然稳定可靠。
工作原理:
- 排序:利用sort参数对结果进行排序,确保分页结果的稳定性。保证结果的唯一性,需要有一个id。
- 定位下一页:
● 使用search_after参数传递上一页最后一个结果的排序值,作为下一页查询的起点。
● ES会根据search_after的值快速定位到上一页的结束位置,开始下一页的查询,避免了深度分页的性能瓶颈。