Java 使用Scroll从Elasticsearch检索大型结果需要花费很长时间
我的开发集群中有3个Elasticsearch节点(版本6.2.4)。所有配置都是默认配置(即使是碎片)。我正在尝试运行一些搜索,将返回数百万条记录。我决定将Scroll与Java高级Rest客户端一起使用。所以我的代码看起来像这样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
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
所以,我有以下问题-
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请求下一组结果。