使用Scroll从Elasticsearch检索大型结果将永远花费

时间:2018-06-20 05:14:39

标签: java elasticsearch

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

    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

所以,我有以下问题-

  1. 这是使用Scroll的正确方法吗?
  2. 进行搜索以返回数百万条记录的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

  

这是使用Scroll的正确方法吗?

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

  

进行搜索以返回数百万条记录的最佳方法是什么?

首先,您必须考虑为什么要这么多记录?您要导出文件吗?否则,检索这么多结果是不合理的。您可以通过在查询中设置terminate_after设置来限制搜索结果总数。

但是,如果您确实需要所有这些记录,则必须将查询分成较小的部分。例如,如果记录中有一个日期字段,请尝试在其上放置过滤器,然后以较小的跨度(例如5分钟为一个步骤)对其进行迭代。

最后,如果您的迭代延迟超过scrollTimeValue,则会出现search_context_missing_exception错误。