美文网首页
ES search_after

ES search_after

作者: yandaxin | 来源:发表于2020-08-19 00:20 被阅读0次

【导读】 一篇非常好的博客,我就是根据这个实现的

https://blog.csdn.net/andybegin/article/details/83864171

search_after的理念是,在不同分片上(假设有5个分片),先按照指定顺序排好,根据我们传的search_after值 ,然后仅取这个值之后的size个文档。这 5*size 个文档拿到Es内存中排序后,返回前size个文档即可。避免了浅分页导致的内存爆炸情况,经实际使用性能良好,ES空闲状态下查询耗时稳定在50ms以内,平均10~20ms。

为了每次文档排序的一致性,每个文档必须有一个全局唯一值,一般采用 _id 。

啥意思呢?想象一个场景,假设我们仅按照create_time倒序排列,如果doc1和doc2的create_time相同,那么完全可能第一次排序是doc1在前,第二次排序doc2在前。①

在取第n页时,es排序结果是(……,doc1 ,doc2,……),我们取走了(……,doc1),那么第n+1页是不是应该取走(doc2,……),

可是再次排序结果可能变了,变成了(……,doc2 ,doc1,……),那么doc2就漏了。

怎么解决这个问题呢?

就是用create_time+_id 进行排序,create_time可能相同,但是_id全局唯一,各个文档按照_id排序每次排序结果都是一样的,这就保证了每次排序都是一致的,不会出现①的情况。

【实现方案】

1、es 指定sort后,每个返回的文档中都会添加一个sort数组,如图,es 就是拿这个数组的组合值去排序的,我们称之为 游标。

1.png

因此代码里做的第一个改动是,将这个sort数组暴露出来,塞到返回值中,记为sortColumns字段 。

然后拿每页最后一个文档的sortColumns作为下一页的search_after,就可以取排在这个文档之后的文档。

2、添加search_after 参数,当有search_after参数时,在查询体里塞一个search_after,query 变成这样,注意sort的列和search_after的列要一一对应。


5.png

这样才能用search_after 去 切割 排序结果。

相关文章

网友评论

      本文标题:ES search_after

      本文链接:https://www.haomeiwen.com/subject/cmiljktx.html