search(13)- elastic4s-histograms:聚合直方圖

来源:https://www.cnblogs.com/tiger-xc/archive/2020/05/15/12897279.html
-Advertisement-
Play Games

在聚合的分組統計中我們會面臨兩種分組元素類型:連續型如時間,自然數等、離散型如地點、產品等。離散型數據本身就代表不同的組別,但連續型數據則需要手工按等長間隔進行切分了。下麵是一個按價錢段聚合的例子: POST /cartxns/_search { "size" : 1, "aggs": { "sal ...


在聚合的分組統計中我們會面臨兩種分組元素類型:連續型如時間,自然數等、離散型如地點、產品等。離散型數據本身就代表不同的組別,但連續型數據則需要手工按等長間隔進行切分了。下麵是一個按價錢段聚合的例子:

POST /cartxns/_search
{
  "size" : 1,
  "aggs": {
    "sales_per_pricerange": {
      "histogram": {
        "field": "price",
        "interval": 20000
      },
      "aggs": {
        "total sales": {
          "sum": {
            "field": "price"
          }
        }
      }
    }
  }
 }
}

在上面這個例子中我們把價錢按20000進行分段。得出0-19999,20000-39999,40000-59999 ... 價格段的度量:

  "aggregations" : {
    "sales_per_pricerange" : {
      "buckets" : [
        {
          "key" : 0.0,
          "doc_count" : 3,
          "total sales" : {
            "value" : 37000.0
          }
        },
        {
          "key" : 20000.0,
          "doc_count" : 4,
          "total sales" : {
            "value" : 95000.0
          }
        },
        {
          "key" : 40000.0,
          "doc_count" : 0,
          "total sales" : {
            "value" : 0.0
          }
        },
        {
          "key" : 60000.0,
          "doc_count" : 0,
          "total sales" : {
            "value" : 0.0
          }
        },
        {
          "key" : 80000.0,
          "doc_count" : 1,
          "total sales" : {
            "value" : 80000.0
          }
        }
      ]
    }
  }

在elastic4s中是這樣表達的:

  val aggHist = search("cartxns").aggregations(
    histogramAggregation("sales_per_price")
      .field("price")
      .interval(20000).subAggregations(
      sumAggregation("total_sales").field("price")
    )
  )
  println(aggHist.show)

  val histResult = client.execute(aggHist).await

  if (histResult.isSuccess)
    histResult.result.aggregations.histogram("sales_per_price").buckets
        .foreach(hb => println(s"${hb.key},${hb.docCount}:${hb.sum("total_sales").value}"))
  else println(s"error: ${histResult.error.reason}")

....

POST:/cartxns/_search?
StringEntity({"aggs":{"sales_per_price":{"histogram":{"interval":20000.0,"field":"price"},"aggs":{"total_sales":{"sum":{"field":"price"}}}}}},Some(application/json))
0.0,3:37000.0
20000.0,4:95000.0
40000.0,0:0.0
60000.0,0:0.0
80000.0,1:80000.0

下麵這個按車款分組統計的就是一個離散元素的聚合統計了:

POST /cartxns/_search
{
  "size" : 1,
  "aggs": {
    "avage price per model" : {
        "terms": {"field" : "make.keyword"},
        "aggs": {
          "average price": {
            "avg": {"field": "price"}
          },
          "max price" : {
            "max": {
              "field": "price"
            }
          },
          "min price" : {
            "min": {
              "field": "price"
            }
          }
          
        }
     }
  }
}

我們可以得到每一款車的平均售價、最低最高售價:

  "aggregations" : {
    "avage price per model" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "honda",
          "doc_count" : 3,
          "max price" : {
            "value" : 20000.0
          },
          "average price" : {
            "value" : 16666.666666666668
          },
          "min price" : {
            "value" : 10000.0
          }
        },
        {
          "key" : "ford",
          "doc_count" : 2,
          "max price" : {
            "value" : 30000.0
          },
          "average price" : {
            "value" : 27500.0
          },
          "min price" : {
            "value" : 25000.0
          }
        },
        {
          "key" : "toyota",
          "doc_count" : 2,
          "max price" : {
            "value" : 15000.0
          },
          "average price" : {
            "value" : 13500.0
          },
          "min price" : {
            "value" : 12000.0
          }
        },
        {
          "key" : "bmw",
          "doc_count" : 1,
          "max price" : {
            "value" : 80000.0
          },
          "average price" : {
            "value" : 80000.0
          },
          "min price" : {
            "value" : 80000.0
          }
        }
      ]
    }
  }

elastic4s示範如下:

  val aggDisc = search("cartxns").aggregations(
    termsAgg("prices_per_model","make.keyword").subAggregations(
      avgAgg("average_price","price"),
      minAgg("min_price","price"),
      maxAgg("max_price","price")
    )
  )
  println(aggDisc.show)
  val discResult = client.execute(aggDisc).await

  if (discResult.isSuccess)
    discResult.result.aggregations.terms("prices_per_model").buckets
      .foreach(mb =>
        println(s"${mb.key},${mb.docCount}:${mb.avg("average_price").value}," +
          s"${mb.min("min_price").value.getOrElse(0)}," +
          s"${mb.max("max_price").value.getOrElse(0)}"))
  else println(s"error: ${discResult.error.causedBy.getOrElse("unknown")}")

...

POST:/cartxns/_search?
StringEntity({"aggs":{"prices_per_model":{"terms":{"field":"make.keyword"},"aggs":{"average_price":{"avg":{"field":"price"}},"min_price":{"min":{"field":"price"}},"max_price":{"max":{"field":"price"}}}}}},Some(application/json))
honda,3:16666.666666666668,10000.0,20000.0
ford,2:27500.0,25000.0,30000.0
toyota,2:13500.0,12000.0,15000.0
bmw,1:80000.0,80000.0,80000.0

date_histogram是一種按時間間隔聚合的統計方法。對於按時間趨勢變化的數據分析十分有用:

POST /cartxns/_search
{
   "aggs": {
     "sales_per_month": {
       "date_histogram": {
         "field": "sold",
         "calendar_interval":"1M",
         "format": "yyyy-MM-dd"
       }
     }
   }
}

...

  "aggregations" : {
    "sales_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2014-01-01",
          "key" : 1388534400000,
          "doc_count" : 1
        },
        {
          "key_as_string" : "2014-02-01",
          "key" : 1391212800000,
          "doc_count" : 1
        },
        {
          "key_as_string" : "2014-03-01",
          "key" : 1393632000000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2014-04-01",
          "key" : 1396310400000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2014-05-01",
          "key" : 1398902400000,
          "doc_count" : 1
        },
        {
          "key_as_string" : "2014-06-01",
          "key" : 1401580800000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2014-07-01",
          "key" : 1404172800000,
          "doc_count" : 1
        },
        {
          "key_as_string" : "2014-08-01",
          "key" : 1406851200000,
          "doc_count" : 1
        },
        {
          "key_as_string" : "2014-09-01",
          "key" : 1409529600000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2014-10-01",
          "key" : 1412121600000,
          "doc_count" : 1
        },
        {
          "key_as_string" : "2014-11-01",
          "key" : 1414800000000,
          "doc_count" : 2
        }
      ]
    }
  }

上面這個例子產生以月為單元的bucket。elastic4s示範:

  val aggDateHist = search("cartxns").aggregations(
    dateHistogramAggregation("sales_per_month")
      .field("sold")
      .calendarInterval(DateHistogramInterval.Month)
      .format("yyyy-MM-dd")
      .minDocCount(1)
  )
  println(aggDateHist.show)

  val dtHistResult = client.execute(aggDateHist).await

  if (dtHistResult.isSuccess)
    dtHistResult.result.aggregations.dateHistogram("sales_per_month").buckets
        .foreach(db => println(s"${db.date},${db.docCount}"))
  else println(s"error: ${dtHistResult.error.causedBy.getOrElse("unknown")}")

...

POST:/cartxns/_search?
StringEntity({"aggs":{"sales_per_month":{"date_histogram":{"calendar_interval":"1M","min_doc_count":1,"format":"yyyy-MM-dd","field":"sold"}}}},Some(application/json))
2014-01-01,1
2014-02-01,1
2014-05-01,1
2014-07-01,1
2014-08-01,1
2014-10-01,1
2014-11-01,2

在以月劃分bucket後可以再進行每個月的深度聚合:

POST /cartxns/_search
{
   "aggs": {
     "sales_per_month": {
       "date_histogram": {
         "field": "sold",
         "calendar_interval":"1M",
         "format": "yyyy-MM-dd"
       },
       "aggs": {
         "per_make_sum": {
           "terms": {
             "field": "make.keyword",
             "size": 10
           },
           "aggs": {
             "sum_price": {
               "sum": {"field": "price"}
             }
           }
         },
         "total_sum": {
           "sum": {
             "field": "price"
           }
         }
       }
     }
   }
}

我們可以得到每個月的銷售總額、每個車款每個月的銷售,如下:

"aggregations" : {
    "sales_per_month" : {
      "buckets" : [
        {
          "key_as_string" : "2014-01-01",
          "key" : 1388534400000,
          "doc_count" : 1,
          "per_make_sum" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "bmw",
                "doc_count" : 1,
                "sum_price" : {
                  "value" : 80000.0
                }
              }
            ]
          },
          "total_sum" : {
            "value" : 80000.0
          }
        },
        {
          "key_as_string" : "2014-02-01",
          "key" : 1391212800000,
          "doc_count" : 1,
          "per_make_sum" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "ford",
                "doc_count" : 1,
                "sum_price" : {
                  "value" : 25000.0
                }
              }
            ]
          },
          "total_sum" : {
            "value" : 25000.0
          }
        },
        {
          "key_as_string" : "2014-03-01",
          "key" : 1393632000000,
          "doc_count" : 0,
          "per_make_sum" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [ ]
          },
          "total_sum" : {
            "value" : 0.0
          }
        },
        {
          "key_as_string" : "2014-04-01",
          "key" : 1396310400000,
          "doc_count" : 0,
          "per_make_sum" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [ ]
          },
          "total_sum" : {
            "value" : 0.0
          }
        },
        {
          "key_as_string" : "2014-05-01",
          "key" : 1398902400000,
          "doc_count" : 1,
          "per_make_sum" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "ford",
                "doc_count" : 1,
                "sum_price" : {
                  "value" : 30000.0
                }
              }
            ]
          },
          "total_sum" : {
            "value" : 30000.0
          }
        },
        {
          "key_as_string" : "2014-06-01",
          "key" : 1401580800000,
          "doc_count" : 0,
          "per_make_sum" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [ ]
          },
          "total_sum" : {
            "value" : 0.0
          }
        },
        {
          "key_as_string" : "2014-07-01",
          "key" : 1404172800000,
          "
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文記錄,如何在 Python Script 中使用 Shebang 行。 Shebang Line 是什麼: 也被叫做 Hashbang Line,只要是一個由,井號和嘆號 開頭,並構成的字元序列 ,就叫做 Shebang Line。在開頭字元之後,可以有一個或數個空白字元。這個字元串,通常只出現 ...
  • 我的LeetCode:https://leetcode cn.com/u/ituring/ 我的LeetCode刷題源碼[GitHub]:https://github.com/izhoujie/Algorithmcii LeetCode 面試題63. 股票的最大利潤 與以下題目相同 前往:LeetC ...
  • 我的LeetCode:https://leetcode cn.com/u/ituring/ 我的LeetCode刷題源碼[GitHub]:https://github.com/izhoujie/Algorithmcii LeetCode 121. 買賣股票的最佳時機 題目 給定一個數組,它的第 i ...
  • 在使用Python時,需要使用各種各樣的庫,通常會使用pip直接安裝,這樣最為簡單也最方便。但最為崩潰的地方在於有時候速度出奇的慢,因為pip預設使用的源為官方源,而官方源在國外。通常的解決方法是更換源,常見的國內源如下所示: Windows下永久更換源 1.在運行視窗或資源管理器中輸入 %APPD ...
  • 這有一個專註Gopher技術成長的開源項目 "「go home」" 背景 作為一名程式員,家裡多多少少會有一些落了灰的電腦,如果把閑置的電腦變成伺服器,不僅有良好的配置,還能用來做各種測試,那就再好不過了。但是區域網的設備怎麼被外網訪問呢?這就靠內網穿透來實現了。 內網穿透又叫 "NAT" 穿透,常 ...
  • ReentrantLock完美實現了互斥,完美解決了併發問題。但是卻意外發現它對於讀多寫少的場景效率實在不行。此時ReentrantReadWriteLock來救場了!一種適用於讀多寫少場景的鎖,可以大幅度提升併發效率,你必須會哦! 序幕 為何引入讀寫鎖? ReentrantReadWriteLoc ...
  • 接上一章, "Windows玩轉Kubernetes系列1 VirtualBox安裝Centos" ,我們開始學習如何在Centos中安裝Docker 準備 關閉防火牆 防火牆一定要提前關閉,否則在後續安裝K8S集群的時候,會有一些問題,執行下麵語句: 關閉Swap 註掉swap 關閉SeLinux ...
  • 開源項目CRI-O(https://github.com/kubernetes-incubator/cri-o),即之前的OCID,旨在不依賴傳統容器引擎的前提下,使開源Kubernetes調度框架可以管理和啟動容器化的工作負載。 使用Google發起、Kubernetes工程師開發的容器運行時介面 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...