qindongliang1922 阅读(742) 评论(0)





ElasticSearch里面的聚合机制非常灵活和强大,今天我们来看下如何在ElasticSearch里面实现分组后,根据sum值进行排序?类似的数据库SQL如下:


select id,sum(c1) as c1 , sum(c2) as c2  from table1 group id order by c1 desc, c2 asc



这是一个比较常见的统计需求,在es也能比较轻松的实现,先看看curl的一个实现例子查询:

GET myindex/_search
{
  "size":0,
  "aggs": {
    "a1": {
      "terms": { 
        "field": "FIELD1",
        "size":0,
        "order": {"a2": "desc"}     
      },
      "aggs":{
        "a2":{
          "sum":{
            "field":"FIELD2.SUBFIELD"
          }
        }
      }
    }
  }
}


然后,我们看下,如何在Java Api里面操作:

首先我们看下造的数据

总共三个字段id,count,code都是int类型的
id,count,code
1,3,1
2,4,1
1,5,2
2,7,1
3,11,7



然后,我们可以将上面的数据插入到es里面,具体的插入代码不在给出,比较简单,直接通过client.prepareIndex方法插入json即可。

下面看下查询代码:
	
	public void groupTest(){

	    //构建查询请求体
        SearchRequestBuilder search = client.prepareSearch("gv_test").setTypes("gv_test");

        //分组字段是id,排序由多个字段排序组成
        TermsBuilder tb= AggregationBuilders.terms("id").field("id").order(Terms.Order.compound(
                Terms.Order.aggregation("sum_count",false)//先按count,降序排
                ,
                Terms.Order.aggregation("sum_code",true)//如果count相等情况下,使用code的和排序
        ));

        //求和字段1
        SumBuilder sb= AggregationBuilders.sum("sum_count").field("count");
        //求和字段2
        SumBuilder sb_code= AggregationBuilders.sum("sum_code").field("code");

        tb.subAggregation(sb);//添加到分组聚合请求中
        tb.subAggregation(sb_code);//添加到分组聚合请求中

        //将分组聚合请求插入到主请求体重
        search.addAggregation(tb);
        //发送查询,获取聚合结果
       Terms tms=  search.get().getAggregations().get("id");
        //遍历每一个分组的key
        for(Terms.Bucket tbb:tms.getBuckets()){
            //获取count的和
            Sum sum= tbb.getAggregations().get("sum_count");
            //获取code的和
            Sum sum2=tbb.getAggregations().get("sum_code");
            System.out.println(tbb.getKey()+"  " + tbb.getDocCount() +"  "+sum.getValue()+"  "+sum2.getValue());
        }
        //释放资源
        client.close();
    }




最终的结果如下:
id,分组个数,count的和,code和
2  2  11.0  2.0
3  1  11.0  7.0
1  2  8.0  3.0


通过对比,我们可以到到结果是准确的,虽然代码量比sql多很多,但是ElasticSearch的聚合功能却是非常的强大和灵活,用来做一些OLAP分析是非常方便的。


有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。
技术债不能欠,健康债更不能欠, 求道之路,与君同行。