Elasticsearch Search Scroll API不会从索引中检索所有文档

时间:2020-03-25 07:45:52

标签: elasticsearch elasticsearch-java-api resthighlevelclient

我想从Elasticsearch检索所有文档,所以我提到了Search Scroll API

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

即使我用另一个索引检查了我有超过1万个文档,也没有返回最后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();

2 个答案:

答案 0 :(得分:0)

今天,在处理来自以下方面的示例时,我遇到了同样的问题:

Elastic Scroll API

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

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

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

答案 1 :(得分: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是一种保护措施,搜索请求占用的堆内存和时间与+大小成正比。

因此max_result_window的默认值为1万次匹配,您还可以将此值设置为其他值。这意味着您可以在1个搜索调用中最多获取1万次匹配,而无需执行多余的分页。

您可以通过在执行搜索调用之前为size指定searchSourceBuilder属性来实现此目的,

searchSourceBuilder.size(10000);