Es Bucket聚合(桶聚合)總結


Buket Aggregations(桶聚合)不像metrics Aggregations(度量聚合)那樣計算字段上的度量,而是創建文檔桶,每個文件桶有效地定義一個文檔集。除了bucket本身之外,bucket聚合還計算並返回“落入”每個bucket的文檔的數量。與度量聚合相反,桶聚合可以嵌套子聚合。這些子聚合將為它們的“父”桶聚合創建的桶進行聚合。ES Bucket Aggregations對標關系型數據庫的(group by)。
首先我們來介紹桶聚合兩個常用參數intervals、time_zone的含義。
1、Intervals
定義桶的間隔,其可選值如下:

  • seconds:1, 5, 10, 30的倍數。
  • minutes:1, 5, 10, 30的倍數。
  • hours:1, 3, 12的倍數。
  • days:1,7的倍數。
  • months:1, 3的倍數。
  • years:1, 5, 10, 20, 50, 100的倍數。

2、Time Zone
對於日期類型,可以使用time_zone來指定時區,可選值可以是相對ISO 8601 utc的相對值,例如+01:00或-08:00,也可以是時區ID,例如America/Los_Angeles。
3、Histogram Aggregation
直方圖聚合,Date Histogram Aggregation是其特例。
動態將文檔中的值按照特定的間隔構建桶,並計算落在該桶的數量,文檔中的值根據如下函數進行近似匹配:
bucket_key = Math.floor((value - offset) / interval) * interval + offset,
其中interval必須是正小數(包含正整數),offset為[0,interval)。
主要支持的參數如下:

  • keyed:響應結果返回組織方式(數組或對象),具體示例請參考日期類直方圖聚合。
  • doc_count:匹配的文檔數量。
  • offset 偏移量:更改每個bucket(桶)的開始時間,例如將offset設置為"10",則上例中返回的一個桶的key為:[10,30),如果offset設置為5,則第一個桶的key為[15,30)。
  • order:默認按照key的升序進行排序,可以通過order字段來指定排序,其值為BucketOrder。其取值:
  • BucketOrder.count(boolean asc):按匹配文檔格式升序/降序排序。
  • BucketOrder.key(boolean asc):按key的升序或降序排序。
  • BucketOrder.aggregation:通過定義一個子聚合進行排序。
  • BucketOrder.compound(List< BucketOrder> orders):創建一個桶排序策略,該策略根據多個條件對桶進行排序。
  • min_doc_count:表示只顯示匹配的文檔大於等於min_doc_count的桶。

4、Date Histogram Aggregation
日期字段直方圖聚合。
4.1 interval 取值

  • milliseconds (ms):毫秒,固定長度,支持倍數,通常使用1000的倍數。
  • seconds (s):
  • minutes (m):分鍾。所有的分鍾從00秒開始。1m,表示在指定時區的第一分鍾00s到下一分鍾00s之間的時間段。{n}m,表示時間間隔,等於n * 60 * 1000 毫秒。
  • hours (h):小時,其分鍾與秒都從00開始。1小時(1h)是指定時區內第一個小時的00:00分鍾到下一個小時的00:00分鍾之間的時間間隔,用來補償其間的任何閏秒,從而使經過該小時的分鍾數和秒數在開始和結束時相同。{n}h,表示時間間隔,等於 n * 60 * 60 * 1000 毫秒的時間間隔。
  • days (d):一天(1d)是在指定的時區內,從一天的開始到第二天的開始的時間間隔。{n}d,表示時間間隔,等於n * 24 * 60 * 60 * 1000毫秒。
  • weeks (w):1周(1w)為開始日:of_week:hour:minute:second與一周的同一天及下一周的時間在指定時區的間隔。不支持 {n}w。
  • months (M):一個月(1M)是本月開始之間的時間間隔的一天與次月的同一天。不支持{n}M
  • quarters (q):季度,不支持{n}q。
  • years (y):年, 不支持{n}y。
    /**
     * 日期直方圖聚合
     */
    @Test
    public void test_Date_Histogram_Aggregation() {
        try {
            //構建日期直方圖聚合  時間間隔,示例中按月統計
            DateHistogramInterval interval = new DateHistogramInterval("1D");
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("items");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            AggregationBuilder aggregationBuild = AggregationBuilders.dateHistogram("birthDay_histogram")
                    .field("birthDay")
                    .dateHistogramInterval(interval)
                    //    .format("yyyy-MM-dd") // 對key的格式化
                    ;
            sourceBuilder.aggregation(aggregationBuild);
            sourceBuilder.size(0);
//            sourceBuilder.query(
//                    QueryBuilders.termQuery("sellerId", 24)
//            );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            }catch (Exception e){
                log.error(e.getMessage());
            }
        }
    }

對應的返回值:

{
    ... //省略常規響應
    "aggregations":{
        "date_histogram#createTime_histogram":{
            "buckets":[
                    "key_as_string":"2015-12-01 00:00:00",
                    "key":1448928000000,
                    "doc_count":6
                },
                {
                    "key_as_string":"2016-01-01 00:00:00",  
                    "key":1451606400000,
                    "doc_count":4
                }
            ]
        }
    }
}

其相應的參數已在上面詳述,在此不重復介紹。
4.3 Date Histogram聚合支持的常用參數
除Histogram Aggregation羅列的參數后,還額外支持如下參數:

  • timeZone 時區指定。
  • offset 偏移量,更改每個bucket(桶)的開始時間,例如將offset設置為"1h",則上例中返回的一個桶的開始時間:“2015-12-01 00:00:00”,則更改為"2015-12-01 01:00:00"
  • format:key格式化,將key使用format格式化后的值設置為key_as_string字段。
  • keyed:返回結果格式化,默認為false,則buckets返回值為數組,如果keyed=true,則對應的返回結果如下:
"aggregations":{
        "date_histogram#createTime_histogram":{
            "buckets":{
                "2015-12-01 00:00:00":{
                    "key_as_string":"2015-12-01 00:00:00",
                    "key":1448928000000,
                    "doc_count":6
                },
                "2016-01-01 00:00:00":{
                    "key_as_string":"2016-01-01 00:00:00",
                    "key":1451606400000,
                    "doc_count":4
                }
            }
        }
    }
}

5、Date Range Aggregation
日期范圍聚合,每個范圍定義[from,to),from,to可支持date mesh格式。其使用示例如下,其他與 Date Histogram類似。

    /**
     * 日期范圍聚合
     */
    @Test
    public void test_Date_range_Aggregation() {
        try {
            //構建日期直方圖聚合  時間間隔,示例中按月統計
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("items");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            AggregationBuilder aggregationBuild = AggregationBuilders.dateRange("birthDay_Time_date_range")
                    .field("birthDay")
                    .format("yyyy-MM")
                    .addRange("quarter_01", "2010-01", "2099-03")
                    //    .format("yyyy-MM-dd") // 對key的格式化
                    ;
            sourceBuilder.aggregation(aggregationBuild);
            sourceBuilder.size(0);
//            sourceBuilder.query(
//                    QueryBuilders.termQuery("sellerId", 24)
//            );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSONObject.toJSONString(result));
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            }catch (Exception e){
                log.error(e.getMessage());
            }
        }
    }

6、Filter Aggregation
聚合中支持首先根據過濾上下文對所有文檔進行刷選,然后再進行聚合計算,例如:

    /**
     * Filter Aggregation
     */
    @Test
    public void test_filter_Aggregation() {
        try {
            //構建日期直方圖聚合  時間間隔,示例中按月統計
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("items");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            AggregationBuilder aggregationBuild = AggregationBuilders.filter("category_filter", QueryBuilders.termQuery("category", "一級"))
                    .subAggregation(AggregationBuilders.avg("avg_price").field("price"));
            sourceBuilder.aggregation(aggregationBuild);
            sourceBuilder.size(0);
//            sourceBuilder.query(
//                    QueryBuilders.termQuery("sellerId", 24)
//            );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            }catch (Exception e){
                log.error(e.getMessage());
            }
        }
    }

其返回結果如下:

{
    "took": 34,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 9,
        "max_score": 0,
        "hits": []
    },
    "aggregations": {
        "filter#category_filter": {
            "doc_count": 4,
            "avg#avg_price": {
                "value": 481.69725
            }
        }
    }
}

7、Filters Aggregation
定義一個多桶聚合,其中每個桶與一個過濾器相關聯。每個bucket將收集與其關聯過濾器匹配的所有文檔。

    /**
     * Filters Aggregation
     */
    @Test
    public void test_filters_aggregation() {
        try {
            //構建日期直方圖聚合  時間間隔,示例中按月統計
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("items");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            AggregationBuilder aggregationBuild = AggregationBuilders.filters("create_filters",
                    QueryBuilders.termQuery("category", "一級"),
                    QueryBuilders.termQuery("category", "二級"))
                    .subAggregation(AggregationBuilders.avg("avg_price").field("price"));
            sourceBuilder.aggregation(aggregationBuild);
            sourceBuilder.size(0);
//            sourceBuilder.query(
//                    QueryBuilders.termQuery("sellerId", 24)
//            );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSONObject.toJSONString(result));
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            }catch (Exception e){
                log.error(e.getMessage());
            }
        }
    }

其返回結果:

{
    "aggregations": {
        "asMap": {
            "create_filters": {
                "buckets": [
                    {
                        "aggregations": {
                            "asMap": {
                                "avg_price": {
                                    "fragment": true,
                                    "name": "avg_price",
                                    "type": "avg",
                                    "value": 481.69725,
                                    "valueAsString": "481.69725"
                                }
                            },
                            "fragment": true
                        },
                        "docCount": 4,
                        "fragment": true,
                        "key": "0",
                        "keyAsString": "0"
                    },
                    {
                        "aggregations": {
                            "asMap": {
                                "avg_price": {
                                    "fragment": true,
                                    "name": "avg_price",
                                    "type": "avg",
                                    "value": 1237.2333333333333,
                                    "valueAsString": "1237.2333333333333"
                                }
                            },
                            "fragment": true
                        },
                        "docCount": 3,
                        "fragment": true,
                        "key": "1",
                        "keyAsString": "1"
                    }
                ],
                "fragment": true,
                "name": "create_filters",
                "type": "filters"
            }
        },
        "fragment": true
    },
    "clusters": {
        "fragment": true,
        "skipped": 0,
        "successful": 0,
        "total": 0
    },
    "failedShards": 0,
    "fragment": false,
    "hits": {
        "fragment": true,
        "hits": [],
        "maxScore": 0,
        "totalHits": 9
    },
    "numReducePhases": 1,
    "profileResults": {},
    "shardFailures": [],
    "skippedShards": 0,
    "successfulShards": 5,
    "timedOut": false,
    "took": {
        "days": 0,
        "daysFrac": 1.6203703703703703e-7,
        "hours": 0,
        "hoursFrac": 0.000003888888888888889,
        "micros": 14000,
        "microsFrac": 14000,
        "millis": 14,
        "millisFrac": 14,
        "minutes": 0,
        "minutesFrac": 0.00023333333333333333,
        "nanos": 14000000,
        "seconds": 0,
        "secondsFrac": 0.014,
        "stringRep": "14ms"
    },
    "totalShards": 5
}

溫馨提示,每一個filter代表一個桶(聚合)。
8、Global Aggregation
全局聚合,會忽略所有的查詢條件,具體從下述例子進行說明:

    /**
     * Global Aggregation
     */
    @Test
    public void test_global_aggregation() {
        try {
            //構建日期直方圖聚合  時間間隔,示例中按月統計
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("items");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            AggregationBuilder aggregationBuild = AggregationBuilders.global("all_producers")
                    .subAggregation(AggregationBuilders
                            .avg("num_avg_aggregation")
                            .field("price"));
            sourceBuilder.aggregation(aggregationBuild);
            sourceBuilder.size(0);
//            sourceBuilder.query(
//                    QueryBuilders.termQuery("sellerId", 24)
//            );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(JSONObject.toJSONString(result));
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            }catch (Exception e){
                log.error(e.getMessage());
            }
        }
    }

對應的返回值如下:

{
    "aggregations": {
        "asMap": {
            "all_producers": {
                "aggregations": {
                    "asMap": {
                        "num_avg_aggregation": {
                            "fragment": true,
                            "name": "num_avg_aggregation",
                            "type": "avg",
                            "value": 755.809888888889,
                            "valueAsString": "755.809888888889"
                        }
                    },
                    "fragment": true
                },
                "docCount": 9,                                     // @2
                "fragment": true,
                "name": "all_producers",
                "type": "global"
            }
        },
        "fragment": true
    },
    "clusters": {
        "fragment": true,
        "skipped": 0,
        "successful": 0,
        "total": 0
    },
    "failedShards": 0,
    "fragment": false,
    "hits": {
        "fragment": true,
        "hits": [],
        "maxScore": 0,
        "totalHits": 4                           // @1
    },
    "numReducePhases": 1,
    "profileResults": {},
    "shardFailures": [],
    "skippedShards": 0,
    "successfulShards": 5,
    "timedOut": false,
    "took": {
        "days": 0,
        "daysFrac": 8.101851851851852e-8,
        "hours": 0,
        "hoursFrac": 0.0000019444444444444444,
        "micros": 7000,
        "microsFrac": 7000,
        "millis": 7,
        "millisFrac": 7,
        "minutes": 0,
        "minutesFrac": 0.00011666666666666667,
        "nanos": 7000000,
        "seconds": 0,
        "secondsFrac": 0.007,
        "stringRep": "7ms"
    },
    "totalShards": 5
}

結果@1:表示符合查詢條件的總個數。
結構@2:表示參與聚合的文檔數量,等於當前庫中文檔總數。

參考博客:https://blog.csdn.net/prestigeding/article/details/88428694


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM