ElasticSearch如何一次查询出全部数据——基于Scroll
elasticsearch 查询结果默认只显示10条,可以通过设置from及size来达到分页的效果(详见附3),但是 from + size <= 10,000,因为index.max_result_window 默认值是10,000,而 from+ size 必须小于index.max_result_window 。因此只能用scroll(一次取一点,分多次取)取出所有的结果,
- scroll相当于传统数据库的游标,具体代码片段如下:
searchresponse scrollresp = client.preparesearch(availableindices)
.settypes(type)
.setscroll(new timevalue(60000))
.setquery(boolquerybuilder)
.setsize(search_hits_size).get(); //max of search_hits_size hits will be returned for each scroll
//scroll until no hits are returned
do {
for (searchhit hit : scrollresp.gethits().gethits()) {
tmpjsonlist.add( (jsonobject) jsonvalue.parse(hit.getsourceasstring()));
}
}
jsonlist.addall(tmpjsonlist);
tmpjsonlist.clear();
scrollresp = client.preparesearchscroll(scrollresp.getscrollid()).setscroll(new timevalue(60000)).execute().actionget();
} while (scrollresp.gethits().gethits().length != 0);
setscroll()里传入的时间,表示一次处理setsize()中size大小的数据的超时时间,即处理一个分页最长不超过的时间,上面的代码表示timeout = 1分钟(详情可搜索scroll context)。scrollresp.getscrollid()每次回生成一个scrollid,如下图:
- 用from + size循环读取的代码片段如下:
int index = 0;
{
tmpjsonlist.clear();
srb.setfrom(math.multiplyexact(index, search_hits_size));
index++;
multisearchresponse.item[] items = sr.get().getresponses();
for (multisearchresponse.item item : items) {
searchresponse response = item.getresponse();
searchhit[] hits = response.gethits().gethits();
if (hits.length != 0) {
for (searchhit hit : hits) {
tmpjsonlist.add((jsonobject) jsonvalue.parse(hit.getsourceasstring());
}
}
}
jsonlist.addall(tmpjsonlist);
}
} while (tmpjsonlist.size() > 0);
其中:search_hits_size = 1000, srb是多条件组合查询,前置代码如下:
querybuilders.foreach(query -> {
boolquerybuilder.must(query);
});
multisearchrequestbuilder sr = client.preparemultisearch();
searchrequestbuilder srb = client.preparesearch().settypes(type).setindices(availableindices).setquery(boolquerybuilder).setsize(search_hits_size);
sr.add(srb);
查询条件的构造代码片段如下(用querybuilders根据需要选择term, range, match等):
stringutil.isempty(l7p)) {
querybuilders.add(querybuilders.termquery(event.field_l7p, l7p));
}
if (!stringutil.isempty(starttime) && stringutil.isempty(endtime)) {
querybuilders.add(querybuilders.rangequery(event.field_start_time).from(starttime));
}
附:
1)using scroll in java
2)scroll
3) from and size
*****************************************************************************************************
精力有限,想法太多,专注做好一件事就行
- 我只是一个程序猿。5年内把代码写好,技术博客字字推敲,坚持零拷贝和原创
- 写博客的意义在于打磨文笔,训练逻辑条理性,加深对知识的系统性理解;如果恰好又对别人有点帮助,那真是一件令人开心的事
*****************************************************************************************************
上一篇: 古代妃子吃住都比一般百姓要好 妃子们为什么都活不了长久
下一篇: 如何根据关键字匹配度排序