使用 Spring Data Elasticsearch 进行“扫描和滚动”查询期间的 Elasticsearch SearchContextMissingException

esn*_*sek 6 java spring elasticsearch spring-data-elasticsearch

我正在使用具有默认集群配置的 elasticsearch 2.2.0。我在使用 spring 数据弹性搜索时遇到扫描和滚动查询的问题。当我执行查询时,我收到如下错误:

[2016-06-29 12:45:52,046][DEBUG][action.search.type       ] [Vector] [155597] Failed to execute query phase
RemoteTransportException[[Vector][10.132.47.95:9300][indices:data/read/search[phase/scan/scroll]]]; nested: SearchContextMissingException[No search context found for id [155597]];
Caused by: SearchContextMissingException[No search context found for id [155597]]
    at org.elasticsearch.search.SearchService.findContext(SearchService.java:611)
    at org.elasticsearch.search.SearchService.executeScan(SearchService.java:311)
    at org.elasticsearch.search.action.SearchServiceTransportAction$SearchScanScrollTransportHandler.messageReceived(SearchServiceTransportAction.java:433)
    at org.elasticsearch.search.action.SearchServiceTransportAction$SearchScanScrollTransportHandler.messageReceived(SearchServiceTransportAction.java:430)
    at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:350)
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)

我的“扫描和滚动”代码:

public List<T> getAllElements(SearchQuery searchQuery) {
    searchQuery.setPageable(new PageRequest(0, PAGE_SIZE));
    String scrollId = elasticsearchTemplate.scan(searchQuery, 1000, false);
    List<T> allElements = new LinkedList<>();
    boolean hasRecords = true;
    while (hasRecords) {
        Page<T> page = elasticsearchTemplate.scroll(scrollId, 5000, resultMapper);
        if (page.hasContent()) {
            allElements.addAll(page.getContent());
        } else {
            hasRecords = false;
        }
    }
    elasticsearchTemplate.clearScroll(scrollId);
    return allElements;
}
Run Code Online (Sandbox Code Playgroud)

当我的查询结果大小小于 PAGE_SIZE 参数时,会出现五次这样的错误。我猜它是每个分片一个。当结果大小大于 PAGE_SIZE 时,错误会多发生几次。我试图重构我的代码以不调用:

Page<T> page = elasticsearchTemplate.scroll(scrollId, 5000, resultMapper);
Run Code Online (Sandbox Code Playgroud)

当我确定页面没有内容时。但它只有在 PAGE_SIZE 大于查询结果时才有效,所以它根本不是解决方案。

我必须补充一点,这只是在 elasticsearch 方面的问题。在客户端,错误被隐藏,并且在每种情况下查询结果都是正确的。有没有人知道是什么导致了这个问题?

谢谢你的帮助,

西蒙。

Val*_*Val 3

如果您的搜索上下文不再存在,通常会发生这种情况。

在您的情况下,您以 1 秒的超时时间开始扫描,然后每次扫描在 5 秒内有效。可能是太低了。保持搜索上下文活动的默认持续时间是1 分钟,因此您应该将其增加到 60 秒,如下所示:

String scrollId = elasticsearchTemplate.scan(searchQuery, 60000, false);
...
Page<T> page = elasticsearchTemplate.scroll(scrollId, 60000, resultMapper);
Run Code Online (Sandbox Code Playgroud)