今天做 codereview 发现以下的代码是有问题的,然后我解释说明这部分代码是有问题的,但是他坚持说没问题,生产也没问题。所以我就怀疑是数据量小,所以根本没有翻页,或者翻页一次就结束了。
然后我就在本地进行调试,最后发现 scrollId 不会变的,后面换了 60w 的数据继续测试,也不会改变,我真顶你的个肺。
测试代码:
// 第一次查询
SearchScrollHits<Book> searchHits = elasticsearchRestTemplate.searchScrollStart(6000, nativeSearchQuery, Book.class, IndexCoordinates.of("book"));
String scrollId = searchScrollHits.getScrollId();
while (searchHits.hasSearchHits()) {
for (SearchHit<Book> searchHit : searchHits.getSearchHits()) {
this.execute(searchHit.getContent());
}
// 后续查询
searchHits = elasticsearchRestTemplate.searchScrollContinue(scrollId, 6000, Book.class, IndexCoordinates.of("book"));
// 他的代码不存在这行的 scrollId = searchHits.getScrollId();
}
因为 scrollId 在非分片的情况下是不会变的,所以即使不用 scrollId = searchHits.getScrollId(); 它也能正常跑,我也是醉了。。。这 tmd 瞎猫碰上死老鼠。
没啥好说的,他代码确实可以跑,ES 也没有用到分片,所以结果也是对的,领导也没说啥😂。
scrollid 可能不变,scroll 得到的 doc 是会变的。
scrollid 保留的是 shard 信息,假如 scroll 查询语句需要路由到 100 个 shard 上查。 scrollid 会比较长,记录这 100 个 shard 。有可能从开始到完成都需要路由到这 100 个 shard ,shardid 都不会变化😒,也有可能随着不断进行 scroll ,需要路由到的 shard 越来越少,shardId 也会越来越短。
那么如果 shardid 不变,es 如何每次拿到不同的数据呢?通过 lastEmittedDoc 保留每个 shard 上应取数据在优先队列中的位置信息,并在 fetch 阶段更新 lastEmittedDoc(因为经过全局排序之后,在 fetch 阶段才能确定在不同 shard 上面取多少条数据)。
虽然我打赌输了,但是我还是不认为那个代码是对的,即使代码是可以正常跑,运行结果也是对的。当然我也不会去改,爱咋滴咋滴,能跑就行。我是坚持不了,尊重他人的思想和认知。
如果是你们会怎么处理呢😂。