1. 程式人生 > >ElasticSearch裡面如何分組後根據sum值排序

ElasticSearch裡面如何分組後根據sum值排序

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),在後臺留言諮詢。 技術債不能欠,健康債更不能欠, 求道之路,與君同行。

輸入圖片說明