ES 查询的 scroll_id 不会变,我真的服了。。

2023-09-21 18:01:10 +08:00
 byte10

背景

今天做 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 上面取多少条数据)。

BTW

虽然我打赌输了,但是我还是不认为那个代码是对的,即使代码是可以正常跑,运行结果也是对的。当然我也不会去改,爱咋滴咋滴,能跑就行。我是坚持不了,尊重他人的思想和认知。

如果是你们会怎么处理呢😂。

399 次点击
所在节点    程序员
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/975955

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX