今天介紹的是使用Elasticsearch Aggregations 計算和加總的功能,什麼是Elasticsearch 的Aggregations,在ES最大的好處是可以用Aggs做計算跟加總,ES已經幫我們做好了計算的套件功能,我們只需要拿來使用就可以,非常的好用又快速。不管是Group by 或Cardinality、Sum使用Aggregations就可以幫你算出你想要的數值。
例如現在格式為
{ "download": 12, "createtime": "2016-01-01", "product": "3c", "version": "1.2.3", "userid": 11224 }
我們將download 數值找出Max數值在Sum,我們要如何下ES Aggs指令如下:
curl -XPOST http://xxx:9200/index/type
{ "query": { "bool": { "must": [ { "match_all": {} } ] } }, "size": 0, "aggs": { "by_group": { "terms": { "field": "product", "size": 0 }, "max_download": { "max": { "field": "download" } } }, "sum_download": { "sum_bucket": { "buckets_path": "product>max_download", "size": 0 } } } }
透過以上指令使用curl查詢,回傳數值是正常,那我們接下來就是用ES所提供的Java API
BoolQueryBuilder query = QueryBuilders.boolQuery().must(QueryBuilders.matchAllQuery()); TermsBuilder aggs = AggregationBuilders.terms("by_product").field("product").size(0) .subAggregation( AggregationBuilders.max("by_max").field("download")).size(0) .subAggregation(AggregationBuilders.sum("by_sum").field("by_product>by_max")).size(0); SearchResponse ResultSet = ES(nodes,nodes2,nodes3).prepareSearch("index").setTypes("type") .setQuery(query) .addAggregation(aggs) .setSize(0) .get(); Aggregations result = ResultSet.getAggregations(); Terms groupby1 = result.get("by_product"); for(Terms.Bucket object : groupby1.getBuckets()) { Terms bymax = object.getAggregations().get("by_max"); Terms bysum = object.getAggregations().get("by_sum"); }
說明一下為什麼在Aggs 為什麼要使用size =0 , size =0 就是將所有的資料顯示出來,如果沒有設定,預設值為10筆資料。另外比較特別的是Top Hits API size就反過來,需要設定為9999999將所有資料顯示。如果設定為0是不會顯示資料,這要注意一下。
在ResultSet設定size=0,因為我們不需要取得內容所以不用顯示出來。
References
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html