ES 日期格式影響聚合效果

最近在使用 date_histogram 參數對日期範圍聚合時,發現聚合結果不正確,分析後發現和 ES 日期格式有關,記錄如下。

date_histogram 是 ES 提供針對日期屬性,進行區間聚合的一種方式,比如可以對如 1 分鐘,1 小時,等時間區間的文檔進行聚合。

舉例來說,我這裏是對幾天內的文檔數據,按照 1 小時的時間區間進行聚合,payload 如下:

{
    "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 小時的間隔進行返回,但實際上返回的結果卻是:

"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 總數也和期待的總數不一致,

後來查詢 ES Date 文檔後發現,ES 針對日期類型,默認的格式爲:strict_date_optional_time||epoch_millis , 也就是毫秒級別。

而之前建立 index 模板時,並未對日期屬性指定 format,所以默認選擇爲上述毫秒格式的時間戳。但是入庫的數據,時間戳爲秒。

自然,在聚合時,ES 會用毫秒的格式去聚合秒的數據,導致結果都是以 1970 開始。

修改也很簡單,在創建 index 模板時,顯示指定爲秒格式即可:

"collect_time": {
    "type": "date",
    "format": "epoch_second"
},

參考

ES 日期區間聚合介紹

ES 日期介紹

ES 日期 format 介紹

ES 聚合過程介紹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章