我正在使用带有默认群集配置的elasticsearch 2.2.0。我使用spring data elasticsearch遇到了扫描和滚动查询的问题。当我执行查询时,我得到这样的错误:
[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)
我的扫描&滚动'代码:
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;
}
当我的查询结果大小小于PAGE_SIZE参数时,这样的错误会发生五次。我想这是每个碎片一个。当结果大小大于PAGE_SIZE时,错误会发生几次。我试图重构我的代码而不打电话:
Page<T> page = elasticsearchTemplate.scroll(scrollId, 5000, resultMapper);
当我确定该页面没有内容时。但它只有在PAGE_SIZE大于查询结果时才有效,因此根本不是解决方案。
我必须补充一点,它仅在弹性搜索方面存在问题。在客户端,错误被隐藏,并且在每种情况下查询结果都是正确的。有谁知道导致这个问题的原因是什么?
感谢您的帮助,
西蒙。
答案 0 :(得分:3)
我遇到了类似的问题,我怀疑Spring Data Elasticsearch有一些关于传递Scroll-ID的内部错误。在我的情况下,我只是试图滚动整个索引,我可以排除@Val关于&#34的回答;如果您的搜索上下文不再存在,通常会发生这种情况&#34;,因为无论持续时间如何都会发生异常。此外,例外在第一页之后开始,并且每隔一个页面查询都会发生。
就我而言,我可以简单地使用elasticsearchTemplate.stream()
。它使用Scroll&amp;内部扫描,似乎正确传递Scroll-ID。哦,它使用起来更简单:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery())
.withPageable(new PageRequest(0, 10000))
.build();
Iterator<Post> postIterator = elasticsearchTemplate.stream(searchQuery, Post.class);
while(postIterator.hasNext()) {
Post post = postIterator.next();
}
答案 1 :(得分:2)
如果ElasticSearch系统关闭连接,我会收到此错误。通常它正是@Val所说的 - 死连接。事情有时会在ES中消失,没有充分理由 - 主节点关闭,数据节点过于拥挤,执行不良查询,Kibana在查询中间同时运行...我被所有这些都击中了时间或其他时间来获得此错误。
建议:初始连接时间 - 1000L可能太短,无法获得所需的内容。如果查询越早结束,它就不会受到伤害。
当我尝试快速提取过多数据时,这也会随机发生;你可能有大量的文件,并试图拉动50,000的PAGESIZE可能有点太多了。我们不知道您为PAGESIZE选择了什么。
建议:将PAGESIZE降低到500以下。或者20.看看这些较小的值是否会减慢错误。
我知道迁移到ES 2.3.3之后我遇到的问题就更少了。
答案 2 :(得分:1)
如果您的搜索环境不再存在,通常会发生这种情况。
在您的情况下,您以1秒的超时开始扫描,然后每次扫描在5秒内仍然存在。它可能太低了。使搜索上下文保持活动状态的default duration是1分钟,所以你应该把它增加到60秒,如下所示:
String scrollId = elasticsearchTemplate.scan(searchQuery, 60000, false);
...
Page<T> page = elasticsearchTemplate.scroll(scrollId, 60000, resultMapper);