6

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

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

弹性搜索有可能吗?

=== 更新

我想进一步指出我的问题,因为现在描述的似乎还不够清楚。对此感到抱歉。

案子:

你有一种饲料,饲料每秒都会增长。如果用户转到提要,他会获得最近的 10 个条目,如果他向下滚动,他想获得接下来的 10 个条目。

由于提要每秒都在增长,因此通常的偏移量/限制(弹性搜索中的来自/大小)无法解决此问题,您将显示已显示的条目或全新的条目,具体取决于第一次请求之间的时间(前 10 个条目)以及对下一个条目的请求。

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

目前我在代码中处理这个问题,我从 Elasticsearch 请求包含所有匹配条目的列表并对其进行迭代,这样我就可以做我想做的一切(毫不奇怪)并提取所需的整体块。

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

4

4 回答 4

2

你只需要创建你的查询 DSL 和一个分页系统

{“大小”:10,“来自”:YOUR_OFFSET }

于 2013-11-08T09:03:15.800 回答
2

这是一个老话题,但感觉自elasticsearch 5.0 以来可用的Search After API 正是需要的。提供上一个文档的 id 及其时间戳,例如:

GET twitter/tweet/_search
{
  "size": 10,
  "query": {
    "match": {
      "title": "elasticsearch"
    }
  },
  "search_after": [
    1463538857,
    "tweet#654323"
  ],
  "sort": [
    {
      "date": "asc"
    },
    {
      "_uid": "desc"
    }
  ]
}

来源:https ://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-after.html

于 2016-12-09T13:24:02.040 回答
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 个连续的结果,直到您获得所有结果

于 2013-11-08T19:19:00.483 回答
0

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

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

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

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

这一切都假设大量的提要永远不会改变,如果文档 Y 在 X 和 Z 之间,它将永远保持在那里。

如果分数是恒定的(这不太可能,因为这意味着它总是会因为提要不断变化而上升),您还可以按最后一个文档的分数以下的所有内容进行过滤。

于 2015-11-30T22:06:21.807 回答