ElasticSearch6.2.4(17)——時間資料處理(date histogram)
時間資料處理(Looking at Time)
如果在ES中,搜尋是最常見的行為,那麼建立日期柱狀圖(Date Histogram)肯定是第二常見的。為什麼要使用日期柱狀圖呢?
想象在你的資料中有一個時間戳。資料是什麼不重要-Apache日誌事件,股票交易日期,棒球比賽時間-任何擁有時間戳的資料都能通過日期柱狀圖受益。當你有時間戳時,你經常會想建立基於時間的指標資訊:
-
今年的每個月銷售了多少輛車?
-
過去的12小時中,這隻股票的價格是多少?
-
上週每個小時我們的網站的平均延遲是多少?
常規的histogram通常使用條形圖來表示,而date histogram傾向於被裝換為線圖(Line Graph)來表達時間序列(Time Series)。很多公司使用ES就是為了對時間序列資料進行分析。
date_histogram的工作方式和常規的histogram類似。常規的histogram是基於數值欄位來建立數值區間的桶,而date_histogram則是基於時間區間來建立桶。因此每個桶是按照某個特定的日曆時間定義的(比如,1個月或者是2.5天)。
常規Histogram能夠和日期一起使用嗎?
從技術上而言,是可以的。常規的histogram桶可以和日期一起使用。但是,它並懂日期相關的資訊(Not calendar-aware)。而對於date_histogram,你可以將間隔(Interval)指定為1個月,它知道2月份比12月份要短。date_histogram還能夠和時區一同工作,因此你可以根據使用者的時區來對圖形進行定製,而不是根據伺服器。
常規的histogram會將日期理解為數值,這意味著你必須將間隔以毫秒的形式指定。同時聚合也不理解日曆間隔,所以它對於日期幾乎是沒法使用的。
第一個例子中,我們會建立一個簡單的線圖(Line Chart)來回答這個問題:每個月銷售了多少輛車?
GET /cars/transactions/_search?search_type=count { "aggs": { "sales": { "date_histogram": { "field": "sold", "interval": "month", "format": "yyyy-MM-dd" } } } }
在查詢中有一個聚合,它為每個月建立了一個桶。它能夠告訴我們每個月銷售了多少輛車。同時指定了一個額外的格式引數讓桶擁有更"美觀"的鍵值。在內部,日期被簡單地表示成數值。然而這會讓UI設計師生氣,因此使用格式引數可以讓日期以更常見的格式進行表示。
得到的響應符合預期,但是也有一點意外(看看你能夠察覺到):
{
...
"aggregations": {
"sales": {
"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-05-01",
"key": 1398902400000,
"doc_count": 1
},
{
"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-10-01",
"key": 1412121600000,
"doc_count": 1
},
{
"key_as_string": "2014-11-01",
"key": 1414800000000,
"doc_count": 2
}
]
...
}
聚合完整地被表達出來了。你能看到其中有用來表示月份的桶,每個桶中的文件數量,以及漂亮的key_as_string。
返回空桶
發現在上面的響應中的奇怪之處了嗎?
Yep, that’s right. We are missing a few months! By default, the date_histogram (and histogram too) returns only buckets that have a nonzero document count. 是的,我們缺失了幾個月!預設情況下,date_histogram(以及histogram)只會返回文件數量大於0的桶。
這意味著得到的histogram響應是最小的。但是有些時候該行為並不是我們想要的。對於很多應用而言,你需要將得到的響應直接置入到一個圖形庫中,而不需要任何額外的處理。
因此本質上,我們需要返回所有的桶,哪怕其中不含有任何文件。我們可以設定兩個額外的引數來實現這一行為:
GET /cars/transactions/_search?search_type=count
{
"aggs": {
"sales": {
"date_histogram": {
"field": "sold",
"interval": "month",
"format": "yyyy-MM-dd",
"min_doc_count" : 0,
"extended_bounds" : {
"min" : "2014-01-01",
"max" : "2014-12-31"
}
}
}
}
}
以上的min_doc_count引數會強制返回空桶,extended_bounds引數會強制返回一整年的資料。
這兩個引數會強制返回該年中的所有月份,無論它們的文件數量是多少。min_doc_count的意思很容易懂:它強制返回哪怕為空的桶。
extended_bounds引數需要一些解釋。min_doc_count會強制返回空桶,但是預設ES只會返回在你的資料中的最小值和最大值之間的桶。
因此如果你的資料分佈在四月到七月,你得到的桶只會表示四月到七月中的幾個月(可能為空,如果使用了min_doc_count=0)。為了得到一整年的桶,我們需要告訴ES需要得到的桶的範圍。
extended_bounds引數就是用來告訴ES這一範圍的。一旦你添加了這兩個設定,得到的響應就很容易被圖形生成庫處理而最終得到下圖:
另外的例子
我們已經看到過很多次,為了實現更復雜的行為,桶可以巢狀在桶中。為了說明這一點,我們會建立一個用來顯示每個季度,所有制造商的總銷售額的聚合。同時,我們也會在每個季度為每個製造商單獨計算其總銷售額,因此我們能夠知道哪種汽車創造的收益最多:
GET /cars/transactions/_search?search_type=count
{
"aggs": {
"sales": {
"date_histogram": {
"field": "sold",
"interval": "quarter",
"format": "yyyy-MM-dd",
"min_doc_count" : 0,
"extended_bounds" : {
"min" : "2014-01-01",
"max" : "2014-12-31"
}
},
"aggs": {
"per_make_sum": {
"terms": {
"field": "make"
},
"aggs": {
"sum_price": {
"sum": { "field": "price" }
}
}
},
"total_sum": {
"sum": { "field": "price" }
}
}
}
}
}
可以發現,interval引數被設成了quarter。
得到的響應如下(刪除了很多):
{
....
"aggregations": {
"sales": {
"buckets": [
{
"key_as_string": "2014-01-01",
"key": 1388534400000,
"doc_count": 2,
"total_sum": {
"value": 105000
},
"per_make_sum": {
"buckets": [
{
"key": "bmw",
"doc_count": 1,
"sum_price": {
"value": 80000
}
},
{
"key": "ford",
"doc_count": 1,
"sum_price": {
"value": 25000
}
}
]
}
},
...
}
我們可以將該響應放入到一個圖形中,使用一個線圖(Line Chart)來表達總銷售額,一個條形圖來顯示每個製造商的銷售額(每個季度),如下所示:
無限的可能性
顯然它們都是簡單的例子,但是在對聚合進行繪圖時,是存在無限的可能性的。比如,下圖是Kibana中的一個用來進行實時分析的儀表板,它使用了很多聚合:
因為聚合的實時性,類似這樣的儀表板是很容易進行查詢,操作和互動的。這讓它們非常適合非技術人員和分析人員對資料進行分析,而不需要他們建立一個Hadoop任務。
為了建立類似Kibana的強大儀表板,你需要掌握一些高階概念,比如作用域(Scoping),過濾(Filtering)和聚合排序(Sorting Aggregations)。
--------------------- 本文來自 dm_vincent 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/dm_vincent/article/details/42594043?utm_source=copy