相似於直方圖的多桶聚合,但它只能應用於日期值,因爲在Elasticsearch內部將日期表示爲long
值,所以也能夠在日期上使用普通的histogram
,但準確性會受到影響,緣由是基於時間的間隔不是固定的(想一想閏年和一個月的天數),所以,咱們須要對基於時間的數據提供特殊支持。從功能的角度來看,這個直方圖支持與普通直方圖相同的特性,主要的區別是間隔能夠由日期/時間表達式指定。html
請求桶間隔一個月。數據庫
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "month" } } } }
時間間隔可用的表達式:year
(1y
)、quarter
(1q
)、month
(1M
)、week
(1w
)、day
(1d
)、hour
(1h
)、minute
(1M
)、second
(1s
)。數組
時間值也能夠經過時間單位解析所支持的縮寫來指定,注意,不支持小數時間值,可是你能夠經過轉移到另外一個時間單位來解決這個問題(例如,1.5h
能夠被指定爲90m
),還要注意,大於天的時間間隔不支持任意值,但只能是一個單位大(例如,1y
是有效的,2y
不是)。less
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "90m" } } } }
在內部,日期被表示爲64位數字,表示從紀元開始算起的時間戳,這些時間戳做爲桶的key
返回,key_as_string
是與使用format
參數指定的格式轉換成格式化日期字符串相同的時間戳:elasticsearch
若是沒有指定
format
,那麼它將使用字段映射中指定的第一個日期格式。
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "1M", "format" : "yyyy-MM-dd" } } } }
"format" : "yyyy-MM-dd"
=> 支持表達日期格式模式ide
響應:ui
{ ... "aggregations": { "sales_over_time": { "buckets": [ { "key_as_string": "2015-01-01", "key": 1420070400000, "doc_count": 3 }, { "key_as_string": "2015-02-01", "key": 1422748800000, "doc_count": 2 }, { "key_as_string": "2015-03-01", "key": 1425168000000, "doc_count": 2 } ] } } }
在Elasticsearch中日期時間被存儲在UTC,默認狀況下,全部桶和四捨五入都是在UTC中完成的,可使用time_zone
參數指示桶使用不一樣的時區。code
時區能夠指定爲ISO 8601 UTC偏移量(例如+01:00
或-08:00
),也能夠指定爲時區id,這是TZ數據庫(如America/Los_Angeles
)中使用的標識符。orm
考慮下面的示例:htm
PUT my_index/_doc/1?refresh { "date": "2015-10-01T00:30:00Z" } PUT my_index/_doc/2?refresh { "date": "2015-10-01T01:30:00Z" } GET my_index/_search?size=0 { "aggs": { "by_day": { "date_histogram": { "field": "date", "interval": "day" } } } }
若是沒有指定時區,則使用UTC,這將致使將這兩個文檔放入同一天的桶中,該桶從2015年10月1日午夜UTC開始:
{ ... "aggregations": { "by_day": { "buckets": [ { "key_as_string": "2015-10-01T00:00:00.000Z", "key": 1443657600000, "doc_count": 2 } ] } } }
若是指定了-01:00
的time_zone
,那麼午夜從UTC午夜前一小時開始:
GET my_index/_search?size=0 { "aggs": { "by_day": { "date_histogram": { "field": "date", "interval": "day", "time_zone": "-01:00" } } } }
如今第一個文檔落入2015年9月30日的桶,第二個文檔落入2015年10月1日的桶:
{ ... "aggregations": { "by_day": { "buckets": [ { "key_as_string": "2015-09-30T00:00:00.000-01:00", "key": 1443574800000, "doc_count": 1 }, { "key_as_string": "2015-10-01T00:00:00.000-01:00", "key": 1443661200000, "doc_count": 1 } ] } } }
key_as_string
值表示在指定時區中天天的午夜。
當使用遵循DST(夏令時)更改的時區時,與這些更改發生的時刻接近的桶的大小可能與使用interval
預期的大小略有不一樣。例如,考慮在CET
時區啓動DST:2016年3月27日凌晨2點,時鐘撥快1小時至當地時間凌晨3點,當使用day
做爲interval
時,覆蓋當天的桶將只保存23個小時的數據,而其餘桶一般是24小時。對於較短的間隔,如12h,也是如此,在這裏,當DST轉變發生時,咱們在3月27日早上只有一個11小時的桶。
offset
參數用於經過指定的正(+
)或負偏移(-
)的持續時間來更改每一個桶的起始值,例如1h
爲1小時或1d
爲一天,有關更多可能的持續時間選項,請參閱時間單位。
例如,當使用day
的間隔時,每一個桶從午夜運行到午夜,將offset
參數設置爲+6h
將更改每一個桶從早上6點運行到早上6點:
PUT my_index/_doc/1?refresh { "date": "2015-10-01T05:30:00Z" } PUT my_index/_doc/2?refresh { "date": "2015-10-01T06:30:00Z" } GET my_index/_search?size=0 { "aggs": { "by_day": { "date_histogram": { "field": "date", "interval": "day", "offset": "+6h" } } } }
上面的請求將文檔分組爲從早上6點開始的桶,而不是從午夜開始的單個桶:
{ ... "aggregations": { "by_day": { "buckets": [ { "key_as_string": "2015-09-30T06:00:00.000Z", "key": 1443592800000, "doc_count": 1 }, { "key_as_string": "2015-10-01T06:00:00.000Z", "key": 1443679200000, "doc_count": 1 } ] } } }
在進行time_zone
調整以後,計算每一個桶的起始offset
。
將keyed
標誌設置爲true
將把惟一的字符串鍵與每一個桶關聯起來,並以hash而不是數組的形式返回範圍:
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "1M", "format" : "yyyy-MM-dd", "keyed": true } } } }
響應:
{ ... "aggregations": { "sales_over_time": { "buckets": { "2015-01-01": { "key_as_string": "2015-01-01", "key": 1420070400000, "doc_count": 3 }, "2015-02-01": { "key_as_string": "2015-02-01", "key": 1422748800000, "doc_count": 2 }, "2015-03-01": { "key_as_string": "2015-03-01", "key": 1425168000000, "doc_count": 2 } } } } }
與普通直方圖同樣,支持文檔級別腳本和值級別腳本,還可使用order
設置控制返回的桶的順序,並基於min_doc_count
設置過濾返回的桶(默認狀況下,將返回匹配文檔的第一個桶和最後一個桶之間的全部桶)。這個直方圖還支持extended_bounds
設置,它容許擴展直方圖的界限超過數據自己(關於爲何要這樣作的更多信息,請參閱此處的解釋)。
missing
參數定義瞭如何處理缺失值的文檔,默認狀況下,它們將被忽略,但也能夠將它們視爲有值來處理。
POST /sales/_search?size=0 { "aggs" : { "sale_date" : { "date_histogram" : { "field" : "date", "interval": "year", "missing": "2000/01/01" } } } }
publish_date
字段中沒有值的文檔將落入具備值爲2000-01-01
的文檔的同一個桶。
默認狀況下,返回的桶按key
升序排序,不過可使用order
設置控制順序行爲,支持與Terms聚合相同的order
功能。
在6.0.0中已棄用
使用
_key
而不是_time
來根據它們的日期/鍵來排序桶。
在某些狀況下,日期直方圖不能幫助咱們,例如,當咱們須要經過星期幾聚合結果時,在這種狀況下,爲了克服這個問題,咱們可使用一個返回星期幾的腳本:
POST /sales/_search?size=0 { "aggs": { "dayOfWeek": { "terms": { "script": { "lang": "painless", "source": "doc['date'].value.dayOfWeek" } } } } }
響應:
{ ... "aggregations": { "dayOfWeek": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "7", "doc_count": 4 }, { "key": "4", "doc_count": 3 } ] } } }
響應將包含以星期爲鍵的全部桶:1爲星期一,2爲星期二...7爲星期日。