欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ElasticSearch如何一次查询出全部数据——基于Scroll

程序员文章站 2022-05-22 22:09:16
ElasticSearch 用Scroll(对应数据库的游标) 一次查出全部数据 ......

ElasticSearch如何一次查询出全部数据——基于Scroll

elasticsearch 查询结果默认只显示10条,可以通过设置fromsize来达到分页的效果(详见附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,如下图:

ElasticSearch如何一次查询出全部数据——基于Scroll

 

  • 用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年内把代码写好,技术博客字字推敲,坚持零拷贝和原创
  • 写博客的意义在于打磨文笔,训练逻辑条理性,加深对知识的系统性理解;如果恰好又对别人有点帮助,那真是一件令人开心的事

*****************************************************************************************************