1. 程式人生 > 其它 >HM-SpringCloud微服務系列7.1【資料聚合】

HM-SpringCloud微服務系列7.1【資料聚合】

  1. 聚合(aggregations:實現對文件資料的統計、分析、運算。例如:
    • 什麼品牌的手機最受歡迎?
    • 這些手機的平均價格、最高價格、最低價格?
    • 這些手機每月的銷售情況如何?
  2. 實現這些統計功能的比資料庫的sql要方便的多,而且查詢速度非常快,可以實現近實時搜尋效果。

1 聚合的種類

  1. 聚合常見的有三類:
    • 桶(Bucket)聚合:對文件資料做分組,並統計每組數量
      • TermAggregation:按照文件欄位值分組,例如按照品牌值分組、按照國家分組
      • Date Histogram:按照日期階梯分組,例如一週為一組,或者一月為一組
    • 度量(Metric)聚合:對文件資料進行計算,比如:最大值、最小值、平均值等
      • Avg:求平均值
      • Max:求最大值
      • Min:求最小值
      • Stats:同時求max、min、avg、sum等
    • 管道(pipeline)聚合:其它聚合的結果為基礎再做聚合
  2. 注意:參加聚合的欄位必須是keyword、日期、數值、布林型別

2 DSL實現聚合

2.1 Bucket聚合語法

  1. 案例需求:統計所有資料中的酒店品牌有幾種,其實就是按照品牌對資料分組。此時可以根據酒店品牌的名稱做聚合,也就是Bucket聚合,型別為term。

  2. DSL語法

    GET /hotel/_search
    {
      "size": 0,  // 設定size為0,結果中不包含文件,只包含聚合結果
      "aggs": { // 定義聚合
    	"brandAgg": { //給聚合起個名字
    	  "terms": { // 聚合的型別,按照品牌值聚合,所以選擇term
    		"field": "brand", // 參與聚合的欄位
    		"size": 20 // 希望獲取的聚合結果數量
    	  }
    	}
      }
    }
    
  3. 實操

    點選檢視程式碼
    # 聚合功能
    GET /hotel/_search
    {
      "size": 0,
      "aggs": {
    	"brangAgg": {
    	  "terms": {
    		"field": "brand",
    		"size": 10
    	  }
    	}
      }
    }
    
    點選檢視程式碼
    {
      "took" : 584,
      "timed_out" : false,
      "_shards" : {
    	"total" : 1,
    	"successful" : 1,
    	"skipped" : 0,
    	"failed" : 0
      },
      "hits" : {
    	"total" : {
    	  "value" : 201,
    	  "relation" : "eq"
    	},
    	"max_score" : null,
    	"hits" : [ ]
      },
      "aggregations" : {
    	"brangAgg" : {
    	  "doc_count_error_upper_bound" : 0,
    	  "sum_other_doc_count" : 39,
    	  "buckets" : [
    		{
    		  "key" : "7天酒店",
    		  "doc_count" : 30
    		},
    		{
    		  "key" : "如家",
    		  "doc_count" : 30
    		},
    		{
    		  "key" : "皇冠假日",
    		  "doc_count" : 17
    		},
    		{
    		  "key" : "速8",
    		  "doc_count" : 15
    		},
    		{
    		  "key" : "萬怡",
    		  "doc_count" : 13
    		},
    		{
    		  "key" : "華美達",
    		  "doc_count" : 13
    		},
    		{
    		  "key" : "和頤",
    		  "doc_count" : 12
    		},
    		{
    		  "key" : "萬豪",
    		  "doc_count" : 11
    		},
    		{
    		  "key" : "喜來登",
    		  "doc_count" : 11
    		},
    		{
    		  "key" : "希爾頓",
    		  "doc_count" : 10
    		}
    	  ]
    	}
      }
    }
    

2.2 聚合結果排序

  1. 預設情況下,Bucket聚合會統計Bucket內的文件數量,記為_count,並且按照_count降序排序。
  2. 可以指定order屬性,自定義聚合的排序方式:
    GET /hotel/_search
    {
      "size": 0, 
      "aggs": {
    	"brandAgg": {
    	  "terms": {
    		"field": "brand",
    		"order": {
    		  "_count": "asc" // 按照_count升序排列
    		},
    		"size": 20
    	  }
    	}
      }
    }
    
  3. 實操

2.3 限定聚合範圍

  1. 預設情況下,Bucket聚合是對索引庫的所有文件做聚合,但真實場景下,使用者會輸入搜尋條件,因此聚合必須是對搜尋結果聚合。那麼聚合必須新增限定條件。

  2. 我們可以限定要聚合的文件範圍,只要新增query條件即可:

    GET /hotel/_search
    {
      "query": {
    	"range": {
    	  "price": {
    		"lte": 200 // 只對200元以下的文件聚合
    	  }
    	}
      }, 
      "size": 0, 
      "aggs": {
    	"brandAgg": {
    	  "terms": {
    		"field": "brand",
    		"size": 20
    	  }
    	}
      }
    }
    
  3. 實操

    點選檢視程式碼
    # 聚合功能,限定聚合範圍
    GET /hotel/_search
    {
      "query": {
    	"range": {
    	  "price": {
    		"lte": 200
    	  }
    	}
      }, 
      "size": 0,
      "aggs": {
    	"brangAgg": {
    	  "terms": {
    		"field": "brand",
    		"size": 10
    	  }
    	}
      }
    }
    
    點選檢視程式碼
    {
      "took" : 92,
      "timed_out" : false,
      "_shards" : {
    	"total" : 1,
    	"successful" : 1,
    	"skipped" : 0,
    	"failed" : 0
      },
      "hits" : {
    	"total" : {
    	  "value" : 17,
    	  "relation" : "eq"
    	},
    	"max_score" : null,
    	"hits" : [ ]
      },
      "aggregations" : {
    	"brangAgg" : {
    	  "doc_count_error_upper_bound" : 0,
    	  "sum_other_doc_count" : 0,
    	  "buckets" : [
    		{
    		  "key" : "如家",
    		  "doc_count" : 13
    		},
    		{
    		  "key" : "速8",
    		  "doc_count" : 2
    		},
    		{
    		  "key" : "7天酒店",
    		  "doc_count" : 1
    		},
    		{
    		  "key" : "漢庭",
    		  "doc_count" : 1
    		}
    	  ]
    	}
      }
    }
    
    
  4. 小結

2.4 Metric聚合語法

  1. 此前我們對酒店按照品牌分組,形成了一個個桶。
  2. 現在我們需要對桶內的酒店做運算,獲取每個品牌的使用者評分的min、max、avg等值。
  3. 這就要用到Metric聚合了,例如stat聚合:就可以獲取min、max、avg等結果。
  4. DSL語法如下:
    GET /hotel/_search
    {
      "size": 0, 
      "aggs": {
    	"brandAgg": { 
    	  "terms": { 
    		"field": "brand", 
    		"size": 20
    	  },
    	  "aggs": { // 是brands聚合的子聚合,也就是分組後對每組分別計算
    		"score_stats": { // 聚合名稱
    		  "stats": { // 聚合型別,這裡stats可以計算min、max、avg等
    			"field": "score" // 聚合欄位,這裡是score
    		  }
    		}
    	  }
    	}
      }
    }
    

3 RestAPI實現聚合