天天看點

ElasticSearch5.X聚合-條形圖(四)

條形圖編輯

(測試資料:http://blog.csdn.net/wwd0501/article/details/78501842)聚合還有一個令人激動的特性就是能夠十分容易地将它們轉換成圖表和圖形。 本章中, 我們正在通過示例資料來來完成各種各樣的聚合分析,最終,我們将會發現聚合功能是非常強大的。

直方圖 

histogram

 特别有用。 它本質上是一個條形圖,如果有建立報表或分析儀表盤的經驗,那麼我們會毫無疑問的發現裡面有一些圖表是條形圖。 建立直方圖需要指定一個區間,如果我們要為售價建立一個直方圖,可以将間隔設為 20,000。這樣做将會在每個 $20,000 檔建立一個新桶,然後文檔會被分到對應的桶中。

對于儀表盤來說,我們希望知道每個售價區間内汽車的銷量。我們還會想知道每個售價區間内汽車所帶來的收入,可以通過對每個區間内已售汽車的售價求和得到。

可以用 

histogram

 和一個嵌套的 

sum

 度量得到我們想要的答案:

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs":{
      "price":{
         "histogram":{ 
        
ElasticSearch5.X聚合-條形圖(四)
"field": "price", "interval": 20000 }, "aggs":{ "revenue": { "sum": {
ElasticSearch5.X聚合-條形圖(四)
"field" : "price" } } } } } }

拷貝為 CURL 在 SENSE 中檢視  

ElasticSearch5.X聚合-條形圖(四)

histogram

 桶要求兩個參數:一個數值字段以及一個定義桶大小間隔。
ElasticSearch5.X聚合-條形圖(四)

sum

 度量嵌套在每個售價區間内,用來顯示每個區間内的總收入。

如我們所見,查詢是圍繞 

price

 聚合建構的,它包含一個 

histogram

 桶。它要求字段的類型必須是數值型的同時需要設定分組的間隔範圍。 間隔設定為 20,000 意味着我們将會得到如 

[0-19999, 20000-39999, ...]

 這樣的區間。

接着,我們在直方圖内定義嵌套的度量,這個 

sum

 度量,它會對落入某一具體售價區間的文檔中 

price

 字段的值進行求和。 這可以為我們提供每個售價區間的收入,進而可以發現到底是普通家用車賺錢還是奢侈車賺錢。

響應結果如下:

{
...
   "aggregations": {
      "price": {
         "buckets": [
            {
               "key": 0,
               "doc_count": 3,
               "revenue": {
                  "value": 37000
               }
            },
            {
               "key": 20000,
               "doc_count": 4,
               "revenue": {
                  "value": 95000
               }
            },
            {
               "key": 80000,
               "doc_count": 1,
               "revenue": {
                  "value": 80000
               }
            }
         ]
      }
   }
}      

結果很容易了解,不過應該注意到直方圖的鍵值是區間的下限。鍵 

 代表區間 

0-19,999

 ,鍵 

20000

 代表區間 

20,000-39,999

 ,等等。

ElasticSearch5.X聚合-條形圖(四)

我們可能會注意到空的區間,比如:$40,000-60,000,沒有出現在響應中。 

histogram

桶預設會忽略它,因為它有可能會導緻不希望的潛在錯誤輸出。

我們會在下一小節中讨論如何包括空桶。傳回空桶 傳回空 Buckets 。

可以在圖 圖 35 “Sales and Revenue per price bracket” 中看到以上資料直方圖的圖形化表示。

圖 35. Sales and Revenue per price bracket

ElasticSearch5.X聚合-條形圖(四)

當然,我們可以為任何聚合輸出的分類和統計結果建立條形圖,而不隻是 

直方圖

 桶。讓我們以最受歡迎 10 種汽車以及它們的平均售價、标準差這些資訊建立一個條形圖。 我們會用到 

terms

 桶和 

extended_stats

 度量:

GET /cars/transactions/_search
{
  "size" : 0,
  "aggs": {
    "makes": {
      "terms": {
        "field": "make",
        "size": 10
      },
      "aggs": {
        "stats": {
          "extended_stats": {
            "field": "price"
          }
        }
      }
    }
  }
}      

上述代碼會按受歡迎度傳回制造商清單以及它們各自的統計資訊。我們對其中的 

stats.avg

 、 

stats.count

 和 

stats.std_deviation

 資訊特别感興趣,并用 它們計算出标準差:

std_err = std_deviation / count      

建立圖表如圖 圖 36 “Average price of all makes, with error bars” 。

圖 36. Average price of all makes, with error bars

ElasticSearch5.X聚合-條形圖(四)

Java代碼實作 :

/**
     * Description:柱狀圖聚合,用于各種圖表資料的聚合
     * 
     * @author wangweidong
     * CreateTime: 2017年11月10日 上午10:17:54
     *
    */
   @Test
   public void histogramAggregation() {
	   try {
		   String index = "cars";
		   String type = "transactions";
		   Double interval = 20000d;
		   SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type);
		   
		   HistogramAggregationBuilder priceField = AggregationBuilders.histogram("price").field("price").interval(interval);
		   SumAggregationBuilder revenueField = AggregationBuilders.sum("revenue").field("price");
		   priceField.subAggregation(revenueField);
		   
		   searchRequestBuilder.addAggregation(priceField);
	       searchRequestBuilder.setSize(0);
	       SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
	       
	       System.out.println(searchResponse.toString());
		   
	       Histogram histogram = searchResponse.getAggregations().get("price");
		   for (Histogram.Bucket entry : histogram.getBuckets()) {
			   Object key = entry.getKey();      // Term
		       Long count = entry.getDocCount(); // Doc count
		       
		       Aggregations agg = entry.getAggregations();
		       Sum sum = agg.get("revenue");
		       Double revenue = sum.getValue();
		       
		       System.out.println(key + "~" + (interval+(Double)key) + "區間的車有" + count + "輛,此區間總收入:" + revenue);
		   }
	   } catch (Exception e) {
			e.printStackTrace();
	   }
   }
           

文章參考: https://www.elastic.co/guide/cn/elasticsearch/guide/current/_building_bar_charts.html

繼續閱讀