關於MongoDB時間格式轉換和時間段聚合統計的用法總結
一 . 背景需求
在日常的業務需求中,我們往往會根據時間段來統計資料。例如,統計每小時的下單量;每天的庫存變化,這類資訊資料對運營管理很重要。
這類資料統計依賴於各個時間維度,年月日、時分秒都有可能。因為需求變化多樣,並且表的設計有嚴格的規範,我們不可能將訂單的下單時間分別拆分儲存到 年、月、日、時、分、秒、毫秒列(欄位)中。在實際應用中,我們一般都是通過轉換函式進行時間轉換的。
大家可能對關係型資料庫(例如,SQL Server、MySQL)中的時間轉換函式和依據時間段進行聚合操作比較熟悉了,但是對MongoDB中的時間轉換和依據時間聚合比較陌生。所以,我們有必要花費一定時間進行梳理學習一下,拓展豐富自己的知識。
二 . SQL Server資料庫關於時間的轉換和聚合
為了清楚的瞭解這類需求,瞭解時間轉換和統計,我們先從大家熟悉的SQL Server 入手。例如,我們將時間資料儲存為datetime型別。
首先,回顧下SQL Server的時間轉換函式。
1.通過YEAR(),MONTH(),DAY() 獲取年月日資料。
2.通過DATEPART() 函式 返回日期/時間的單獨部分,比如年、月、日、小時、分鐘等等。
3.datename () 返回代表指定日期的指定日期部分的字串。此函式與DATEPART() 類似。
此外,還可以通過convert()
通過這些函式,我們可以進行時間格式的轉換,在轉換函式的基礎上,可以進行時間段內資料量的統計。
例如:基於DATEPART() 函式, 統計2017-10-10到2017-11-10表中每天的資料量。
也可以基於convert() 函式進行統計
三 . MongoDB 資料庫關於時間的轉換和聚合
以上操作是在SQL Server上進行,如果在MongoDB中,應該藉助什麼的函式進行類似的轉換和統計呢?
如果檢視顯示 各種格式的時間,可以通過 $dateToString 進行轉換。
例如通過轉換函式$dateToString,將集合temp_MongoDateTime中的欄位Rec_CreateTime轉換為 年 欄位、月 欄位、日 欄位、年-月-日、和 時:分:秒:毫秒 欄位
程式碼為:
db.temp_MongoDateTime.aggregate(
[
{
$project: {
"_id":0,
"Rec_CreateTime":1,
Year: { $dateToString: { format: "%Y", date: "$Rec_CreateTime" } },
Month: { $dateToString: { format: "%m", date: "$Rec_CreateTime" } },
Day: { $dateToString: { format: "%d", date: "$Rec_CreateTime" } },
yearMonthDay: { $dateToString: { format: "%Y-%m-%d", date: "$Rec_CreateTime" } },
Time: { $dateToString: { format: "%H:%M:%S:%L", date: "$Rec_CreateTime"} }
}
}
]
)
查詢效果如下:
除了$dateToString轉換函式外,MongoDBDB 還有獲取年月日、時分秒的函式,甚至還提供了處於一年中的多少天,一週的第幾天等。
主要函式為$year、$month、$dayOfMonth、 $hour、$minute、$second、$dayOfYear、$dayOfWeek 等。
我們直接看下面的例子好了。執行程式碼:
db.temp_MongoDateTime.aggregate(
[
{
$project:
{
"_id":0,
"Rec_CreateTime":1,
year: { $year: "$Rec_CreateTime" },
month: { $month: "$Rec_CreateTime" },
day: { $dayOfMonth: "$Rec_CreateTime" },
hour: { $hour: "$Rec_CreateTime" },
minutes: { $minute: "$Rec_CreateTime" },
seconds: { $second: "$Rec_CreateTime" },
milliseconds: { $millisecond: "$Rec_CreateTime" },
dayOfYear: { $dayOfYear: "$Rec_CreateTime" },
dayOfWeek: { $dayOfWeek: "$Rec_CreateTime" },
week: { $week: "$Rec_CreateTime" }
}
}
]
)
上面的2個例子都是時間轉換,如果按照時間段集合統計資料呢?其實基於上面的時間轉換函式,藉助MongoDB的聚合框架,同樣可以輕鬆實現。
例如統計1-12 月份,每個月份的資料量,即那個月是旺季。此時基於時間轉換函式 $month,執行程式碼如下:
db.temp_MongoDateTime.aggregate(
[
{
$match:{}
},
{
$group:{_id:{$month:"$Rec_CreateTime"},
count:{$sum:1}}
}
]
)
查詢效果如下:
上面的資料顯示:集合中的記錄按月聚合,10月份有341筆;9月份有48筆。其中欄位_id 代表了月份。
我們再舉一個例子,例如統計 集合temp_MongoDateTime 在 2016-10-05 05:51:50 到 2018-10-06 05:51:50 這段時間內,0-24 小時內,每小時的分佈情況。即,每天那個時辰(小時)下單量比較多。
此時基於時間轉換函式 $hour ,程式碼如下:
db.temp_MongoDateTime.aggregate(
[
{
$match:{
"Rec_CreateTime":{$gte:ISODate("2016-10-05 05:51:50"),$lte:ISODate("2018-10-06 05:51:50")}
}
},
{$group:{
_id:{ $hour: "$Rec_CreateTime" },
count:{$sum:1}
}
}
]
)
查詢結果顯示如下:
再舉一個關於時間聚合統計的例子,這個例子是基於時間轉換函式$dateToString的。
例如統計每天的資料量,即每天的資料分佈情況。這個每天是按 年-月-日統計分佈的。
程式碼如下:
db.temp_MongoDateTime.aggregate(
[
{
$match:{
"Rec_CreateTime":{$gte:ISODate("2016-10-05 05:51:50"),$lte:ISODate("2018-10-06 05:51:50")}
}
},
{$group:{
_id:{ $dateToString: { format: "%Y-%m-%d", date: "$Rec_CreateTime" } },
count:{$sum:1}
}
}
]
)
查詢效果顯示如下:
四 . 總結
和關係型資料庫 SQL Server 一樣,MongoDB資料庫通過自身的時間轉換函式,例如, $dateToString、$year、$month、$dayOfMonth、 $hour、$minute、$second、$dayOfYear、$dayOfWeek等,也可以輕鬆實現時間轉換和基於時間段的聚合統計。
本文版權歸作者所有,未經作者同意不得轉載,謝謝配合!!!