ElasticSearch裡面如何分組後根據sum值排序
阿新 • • 發佈:2019-02-06
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),在後臺留言諮詢。 技術債不能欠,健康債更不能欠, 求道之路,與君同行。