3

我想从 Elasticsearch 中检索所有文档,所以我参考了Search Scroll API

但我的问题是,它没有返回所有文档,我在一个索引中有 36 个文档,因为它只返回 26 个。

即使当我检查另一个索引时,我有超过 10k 个文档,它也没有返回最后 10 个文档。

我真的不知道为什么它会这样返回它!任何帮助将不胜感激!提前致谢!

在我尝试过的代码下方:

final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
SearchRequest searchRequest = new SearchRequest("myindex");
searchRequest.scroll(scroll);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query("")//here some query;
searchRequest.source(searchSourceBuilder);

SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); 
String scrollId = searchResponse.getScrollId();
SearchHit[] searchHits = searchResponse.getHits().getHits();

while (searchHits != null && searchHits.length > 0) { 
    
    SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); 
    scrollRequest.scroll(scroll);
    searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
    scrollId = searchResponse.getScrollId();
    searchHits = searchResponse.getHits().getHits();
    for (SearchHits hit: searchHits){
       String source=hit.getSourceAsString();
    }
}

ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); 
clearScrollRequest.addScrollId(scrollId);
ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
boolean succeeded = clearScrollResponse.isSucceeded();
4

2 回答 2

0

您应该更改您的 while 循环逻辑以先执行命中迭代,然后再执行滚动。

while (searchHits != null && searchHits.length > 0) {

    // execute this block first otherwise the scroll will overwrite the initial hits.
    for (SearchHits hit: searchHits){
        String source=hit.getSourceAsString();
    }

    SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
    scrollRequest.scroll(scroll);
    searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
    scrollId = searchResponse.getScrollId();
    searchHits = searchResponse.getHits().getHits();
}

要考虑的另一件事是您可以增加响应命中大小。来自文档:

默认为 10,000 的 index.max_result_window 是一种保障,搜索请求占用堆内存和时间与 from + size 成正比。

所以默认值为max_result_window10k hits,您也可以将此值设置为其他值。这意味着您可以在 1 个搜索调用中获取多达 10k 次点击,而不是执行冗余分页。

您可以通过在执行搜索调用之前指定size属性来执行此操作,如下所示:searchSourceBuilder

searchSourceBuilder.size(10000); 
于 2020-10-20T14:14:30.700 回答
0

今天我在使用以下示例时遇到了同样的问题:

弹性滚动 API

首先,关于您错过的文档 - 10 是请求大小的默认值,基于此我们可以假设您的一个请求没有得到正确处理。在您的代码中,未处理第一批 10 个文档:

SearchHit[] searchHits = searchResponse.getHits().getHits();

while循环之前,您应该遍历您的searchHits。从第一次开始,我在官方文件中并不清楚。

于 2020-10-20T13:27:34.653 回答