elasticsearch,Java,elasticsearch" /> elasticsearch,Java,elasticsearch" />

Java 使用Scroll从Elasticsearch检索大型结果需要花费很长时间

Java 使用Scroll从Elasticsearch检索大型结果需要花费很长时间,java,elasticsearch,Java,elasticsearch,我的开发集群中有3个Elasticsearch节点(版本6.2.4)。所有配置都是默认配置(即使是碎片)。我正在尝试运行一些搜索,将返回数百万条记录。我决定将Scroll与Java高级Rest客户端一起使用。所以我的代码看起来像这样 MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("galaxy", galaxyName); SearchSourceBuilder searchSourceBuilder = new Sea

我的开发集群中有3个Elasticsearch节点(版本6.2.4)。所有配置都是默认配置(即使是碎片)。我正在尝试运行一些搜索,将返回数百万条记录。我决定将Scroll与Java高级Rest客户端一起使用。所以我的代码看起来像这样

MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("galaxy", galaxyName);

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(matchQueryBuilder);
searchSourceBuilder.size(scrollSize);

SearchRequest searchRequest = new SearchRequest();

searchRequest.indices(galaxyIndexName);
searchRequest.source(searchSourceBuilder);
searchRequest.scroll(TimeValue.timeValueSeconds(scrollTimeValue));

SearchResponse searchResponse = restHighLevelClient.search(searchRequest);

StarCollection starCollection = new StarCollection();

boolean moreResultsExist = true;

int resultCount = 0;

while (moreResultsExist) {

    String scrollId = searchResponse.getScrollId();

    for (SearchHit searchHit : searchResponse.getHits()) {

        Star star = objectMapper.readValue(searchHit.getSourceAsString(), Star.class);
        resultCount++;

        starCollection.addContentsItem(star);
    }

    if (resultCount >= searchResponse.getHits().getTotalHits()) {

        moreResultsExist = false;

        ClearScrollRequest request = new ClearScrollRequest();
        request.addScrollId(scrollId);
        restHighLevelClient.clearScroll(request);
    }

    SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
    scrollRequest.scroll(TimeValue.timeValueSeconds(scrollTimeValue));
    searchResponse = restHighLevelClient.searchScroll(scrollRequest);
}
现在,当我运行返回150万个文档的搜索时,它需要花费很长时间。我的方法永远不会结束。有时我会有例外,比如

org.elasticsearch.ElasticsearchException: Elasticsearch exception [type=search_context_missing_exception, reason=No search context found for id
所以,我有以下问题-

  • 这是使用Scroll的正确方法吗
  • 搜索返回数百万条记录的最佳方式是什么
  • 这是使用Scroll的正确方法吗

    是的,滚动是检索大规模结果的最佳方式

    搜索返回数百万条记录的最佳方式是什么

    首先你必须想一想为什么你想要这么多唱片?您正在导出文档吗?否则检索这么多结果是不合理的。您可以通过在查询中设置
    terminate\u后设置
    settings来限制总搜索结果

    但是如果你真的需要所有这些记录,你必须把你的查询分解成更小的部分。例如,如果记录中有一个日期字段,请尝试对其进行筛选,并以较小的跨度对其进行迭代(例如5分钟步长)


    最后,如果您在迭代中的延迟超过了
    scrollTimeValue
    ,则会出现
    search\u context\u missing\u exception
    错误。

    可能会使用较小的
    scrollSize
    ,也可能会增加
    scrollTimeValue
    。我尝试了不同的滚动大小,比如100、500、1000。获取100个文档需要1.5秒,这仍然很高。如果不知道您有什么样的框,很难判断。实际上,我的用例需要这种数据作为响应。我不能添加任何过滤器。但是你的建议让我深思,我考虑了一些策略-1)划分索引-索引本身可以根据时间分解为多个索引,并且可以使用线程同时对所有索引启动多个搜索查询。2) Return paginated result-我可以返回一批结果和页面Id作为响应,消费者可以使用页面Id请求下一组结果。