接上篇,我们构造各种条件,可以进行各种查询,找到满足我们需求的数据,但是如果数据量大,不知道大家发现一个问题没,那就是你getHits,只能get到一万,一万之后的没办法,那是因为普通的搜索只能支持到这里......
不懂?那这么讲吧,咱们之前用的搜索,相当于MySQL的limit,这种分页,数据量少的话怎么玩都行,但是如果量大呢,比如我现在十个亿数据,你在ES给我分个页试试,你分页的前提是都查出来,排序,全都怼在内存了,大哥,你内存是多大啊,现在明白为啥之前那种搜索只能取出一万数据了吧
当然了,ES既然是搞大数据的,那它当然不会蠢到让大家只能取出一万笔数据,于是,就出现了滚动查询--Scroll
什么是滚动插叙呢,原理是什么呢?
滚动查询和原生查询,一个相当于我们翻书,可以跳,一个相当于长图,看到哪儿显示哪儿,这也是他们的异同点:滚动查询无论查多少数据都可以,但是不能翻页,不支持分页,普通查询,支持翻页分页,但是只支持一万笔以内的数据量
上代码
@Autowired
private RestHighLevelClient restHighLevelClient;
public void scrollDemo() {
//构造查询条件
SearchRequest searchRequest = new SearchRequest("索引库");
SearchSourceBuilder builder = new SearchSourceBuilder();
//设置查询超时时间
Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
builder.query(QueryBuilders.rangeQuery("字段").gte("开始时间").lte("结束时间"));
//设置最多一次能够取出10000笔数据,从第10001笔数据开始,将开启滚动查询 PS:滚动查询也属于这一次查询,只不过因为一次查不完,分多次查
builder.size(10000);
searchRequest.source(builder);
//将滚动放入
searchRequest.scroll(scroll);
SearchResponse searchResponse = null;
try {
searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
log.error("查询索引库失败", e.getMessage(), e);
}
SearchHits hits = searchResponse.getHits();
//记录要滚动的ID
String scrollId = searchResponse.getScrollId();
//TODO 对结果集的处理
//滚动查询部分,将从第10001笔数据开始取
SearchHit[] hitsScroll = hits.getHits();
while (hitsScroll != null && hitsScroll.length > 0 ) {
//构造滚动查询条件
SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
searchScrollRequest.scroll(scroll);
try {
//响应必须是上面的响应对象,需要对上一层进行覆盖
searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
log.error("滚动查询失败",e.getMessage(),e);
}
scrollId = searchResponse.getScrollId();
hits = searchResponse.getHits();
hitsScroll = hits.getHits();
//TODO 同上面完全一致的结果集处理
}
//清除滚动,否则影响下次查询
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
clearScrollRequest.addScrollId(scrollId);
ClearScrollResponse clearScrollResponse = null;
try {
clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
log.error("滚动查询清除失败",e.getMessage(),e);
}
//清除滚动是否成功
boolean succeeded = clearScrollResponse.isSucceeded();
}
从上边的代码可以看出来,滚动查询其实也很简单,普通查询只能查一万笔,滚动查询就是从第一万零一笔数据开始,进行滚动,后续一直滚动,直到没有,所以滚动查询出来的结果逻辑处理,和上边普通查询是一样的,另外,滚动查询是建立在普通查询基础上的!!!
以上就是ES的滚动查询,可以解决普通查询只能查询一万笔的限制