前言
es查询速度比关系型数据库确实快很多,特别是海量数据的查询。但是查询操作比较难受,特别是复杂聚合操作的时候。
官网介绍
java api在官网上有,网上也有很多demo,文章主要分享对聚合的操作。
前置条件
需求是用java api实现下列查询:
SELECT SUM(AssetsId) as sum1,a+b FROM table GROUP BY a+b ORDER BY sum1 DESC LIMIT 0,10;
实际项目里需是对不同的求和进行排序,要实现聚合-求和-排序-分页。
聚合
这里需要把两个字段拼接成一个字段聚合
TermsAggregationBuilder tb = AggregationBuilders.terms("all_ip_stat")
.script(new Script("doc['ip_dst_addr'].value+'='+doc['ip_src_addr'].value"));
求和
tb.subAggregation(AggregationBuilders.sum("total_bytes")
.script(new Script("doc['orig_bytes'].value+doc['resp_bytes'].value")));
tb.subAggregation(AggregationBuilders.sum("up_total_bytes").field("orig_bytes"));
tb.subAggregation(AggregationBuilders.sum("down_total_bytes").field("resp_bytes"));
排序
对求和的三个字段排序,可以指定字段名
tb.order(Terms.Order.aggregation(sortFiled, sort));
sortFiled排序的字段。sort顺序,true升序,false降序。
分页
java api有对查询分页的,但是没搜到对聚合分页,临时的解决办法是先查出来再分页,这个方法有个很明显的弊端,查出来的数据量非常大的时候分页就是灾难,好在需求只需要前N条
![](https://img.haomeiwen.com/i14480165/a79d32063b1ad869.jpg)
es查询都需要指定查询的条数,没指定会只返回10条数据。
对聚合指定
tb.size(100);
查询指定
SearchRequestBuilder searchRequestBuilder =client.prepareSearch(index).setQuery(query)
.setSize(numPerPage).setFrom(from).setExplain(true)
.addSort("timestamp", SortOrder.DESC);
组装查询条件
SearchRequestBuilder searchRequestBuilder = initBuilder(index).setQuery(query)
.addAggregation(tb);
先查出来再分页不是最好的办法,有空在找找有没有好的方法补上。
网友评论