Elasticsearch在特定文档ID之后获取匹配的文档

时间:2013-11-08 05:36:45

标签: elasticsearch offset

当我搜索文档时,我取了前10个并将它们提供给视图,如果用户滚动到列表的末尾,则应显示下10个元素。

我知道显示文档的最后一个文档ID,现在我必须得到下一个10.基本上我会执行完全相同的搜索,偏移量为10但是能够使用相同的搜索会更好查询,将最后检索到的文档的文档ID放入其中,并在具有该ID的文档之后检索匹配的文档。

弹性搜索可以吗?

===更新

我想更多地指出我的问题,因为它似乎不够清晰,因为它现在被描述。对不起。

案例:

你有一种饲料,饲料每秒都会生长。如果用户访问该Feed,他会获得最近的10个条目,如果他向下滚动,则他希望获得接下来的10个条目。

由于Feed每秒都在增长,因此通常的偏移/限制(来自elasticsearch中的/ size)无法解决此问题,您将显示已显示的条目或完全更新的条目,具体取决于第一次请求之间的时间(第一次) 10个条目)和下一个条目的请求。

在已经显示的条目之后获取接下来的10个元素的请求给后端提供了显示的最后一个条目的id。后端知道忽略此特定条目之前的所有条目。

目前我正在代码中处理这个问题,我请求列表中包含来自Elasticsearch的所有匹配条目并迭代它,这样我就可以做我想做的一切(毫不奇怪)并提取所需的一部分内容。

我的问题是:在弹性搜索中是否有针对此问题的解决方案。因为在我的路上解决问题并不是最快的。

4 个答案:

答案 0 :(得分:2)

您只需使用

创建查询DSL和分页系统
  

{“size”:10,“from”:YOUR_OFFSET}

答案 1 :(得分:0)

如果我正确理解了您的问题,那么您可以使用ES卷轴进行此类操作。 这是一个关于如何在java中执行此操作的示例,请注意它使用SearchType.SCAN

        SearchRequestBuilder requestBuilder = ....getClient().prepareSearch(indices)

        /**
         * Set up scroll and go from there.....
         * To do that need to change search type to <code>SearchType.SCAN</code>
         * and set up scroll it self
         * Once search type and scroll are set and search is executed, whoever
         * handles the result will need to check and poll the scroll
         */
        requestBuilder.setSearchType(SearchType.SCAN);
        requestBuilder.setScroll(new TimeValue(SCROLL_WINDOW_IN_MILLISECONDS)); // this is in MILLISECONDS
        requestBuilder.setSize(10); // this is how many hits per shrad per scroll will be returned


        SearchResponse response = requestBuilder.execute().actionGet();
        while (true) {
            results = client.prepareSearchScroll(results.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
            if (results.getHits().getHits().length == 0) {
                break;
            }
                     // do what you need to do w/ scroll result here
}

所以每次在while循环内部,你都会获得10个结果,直到你获得所有结果

答案 2 :(得分:0)

我知道这已经过时了,但我遇到了同样的困境,我宁愿大声思考。

在该Feed中,您似乎关心每个请求的相关文档越来越少。我不是故意说时间戳/评论计数等,就ES而言,你谈的是可以通过很多因素计算的分数,你想要的是继续搜索那条得分之路。

我想到的解决方案是:如果您还关心更多相关文档(例如Facebook会向您显示“X新故事可用”),您可以先从头开始搜索,直到找到您遇到的第一个文档(之前最相关的那个),并且通过将之前文档的数量添加到您已经在Feed中显示的文档计数,您可以确定估计的偏移量(在竞争条件下您可能会得到一些重复项,只需删除它们)

所以你真正需要做的就是搜索顶部,直到你到达第一个文档,然后搜索估计的底部并删除与上一个文档相关的所有内容。

这一切都假设饲料的批量永远不会改变,如果文件Y在X和Z之间,它将永远保留在那里。

如果分数不变(不太可能,因为这意味着它总是会因饲料不断变化而上升),您也可以过滤掉最后一个文档得分以下的所有内容。

答案 3 :(得分:0)

这是一个古老的主题,但它认为自从elasticsearch 5.0以来可用的Search After API完全可以满足需要。提供上一个文档的ID及其时间戳,例如:

Edit as Fields

来源:Apple's documentation.