Elasticsearch Scroll查询无返回文档,循环无法执行求助
排查Elasticsearch Scroll功能异常的问题
我来帮你梳理下代码里的几个关键问题,这些应该就是导致你遇到现象的核心原因:
1. 循环内的遍历对象完全错误
看你循环里的这段代码:
while (resultsscroll.Documents.Any()) { foreach (var doc in results) { results.Add(doc); } resultsscroll = client.Scroll<MyModel>("10m", resultsscroll.ScrollId); }
你遍历的是空列表results,而不是当前scroll请求返回的resultsscroll.Documents——这直接导致你根本没有把scroll获取到的文档添加到结果里,而且因为results初始是空的,这个foreach循环完全不会执行。正确的写法应该是:
foreach (var doc in resultsscroll.Documents) { results.Add(doc); }
2. 遗漏了初始搜索的结果
你第一次调用client.Search得到的scanResults已经包含了2000条记录,但你完全没把这部分数据添加到results里,直接跳去调用scroll,这会导致这部分初始数据丢失。必须在进入scroll循环前,先把scanResults.Documents的内容加到结果列表中。
3. SearchType.Scan早已被废弃
在Elasticsearch 2.0之后,Scan搜索类型就被官方废弃了,它的功能已经被常规的scroll API完全替代。所以当你指定.SearchType(Nest.SearchType.Scan)时,Elasticsearch不会正确处理这个请求,直接返回0条记录是正常现象,你完全不需要再使用这个参数。
修正后的完整代码
把这些问题修复后,代码应该是这样的:
var results = new List<MyModel>(); // 初始搜索获取第一批数据和scroll id var initialSearch = client.Search<MyModel>(s => s .Index("myindex") .Type("MyIndexType") .From(0) .Size(2000) .Query(q => q.QueryString(qs => qs.Query(query))) .Scroll("5m") ); // 先把初始搜索的结果加入列表 results.AddRange(initialSearch.Documents); // 开始scroll循环拉取剩余数据 var scrollResponse = client.Scroll<MyModel>("10m", initialSearch.ScrollId); while (scrollResponse.Documents.Any()) { results.AddRange(scrollResponse.Documents); // 更新scroll id,发起下一次scroll请求 scrollResponse = client.Scroll<MyModel>("10m", scrollResponse.ScrollId); } // 最后记得清理scroll上下文,避免占用服务器资源 client.ClearScroll(c => c.ScrollId(initialSearch.ScrollId, scrollResponse.ScrollId)); return results;
额外提醒:所有scroll操作完成后,一定要调用ClearScroll清理Elasticsearch的scroll上下文,不然这些上下文会占用资源直到超时自动释放。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

