最近在使用 date_histogram
參數對日期範圍聚合時,發現聚合結果不正確,分析後發現和 ES 日期格式有關,記錄以下。html
date_histogram
是 ES 提供針對日期屬性,進行區間聚合的一種方式,好比能夠對如 1 分鐘,1 小時,等時間區間的文檔進行聚合。sql
舉例來講,我這裏是對幾天內的文檔數據,按照 1 小時的時間區間進行聚合,payload 以下:app
{ "size": 100, "query": { "range": { "collect_time": { "gte": 1610265800, # 開始時間 "lt": "now" # 結束時間 } } }, "aggs": { "group_by_hour": { "date_histogram": { "field": "collect_time", # collect_time 爲日期屬性,按照該屬性進行聚合 "interval": "hour", # 聚合的區間爲小時 "format": "yyyy-MM-dd-hh" # 返回結果中的日期顯示格式 }, "aggs": { "avgrtt": { "avg": { "field": "avgrtt" # 聚合待求平均值的字段 } } } } } }
按照期待的理解,返回的數據應該按照 1 小時的間隔進行返回,但實際上返回的結果倒是:elasticsearch
"aggregations": { "group_by_hour": { "buckets": [ { "key_as_string": "1970-01-19-03", "key": 1609200000, "doc_count": 70, "avgrtt": { "value": 1.0 } } ] } }
傳入的最小日期爲 1610265800 ,也就是 2021-01-10 16:03:20. 但這裏聚合後的時間結果是 1970-01-19-03。說明聚合的粒度根本不對,並且這裏聚合 doc 總數也和期待的總數不一致,ide
後來查詢 ES Date 文檔後發現,ES 針對日期類型,默認的格式爲:strict_date_optional_time||epoch_millis
, 也就是毫秒級別。ui
而以前創建 index 模板時,並未對日期屬性指定 format,因此默認選擇爲上述毫秒格式的時間戳。可是入庫的數據,時間戳爲秒。code
天然,在聚合時,ES 會用毫秒的格式去聚合秒的數據,致使結果都是以 1970
開始。orm
修改也很簡單,在建立 index 模板時,顯示指定爲秒格式便可:htm
"collect_time": { "type": "date", "format": "epoch_second" },