關於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等,也可以輕松實現時間轉換和基於時間段的聚合統計。

 

本文版權歸作者所有,未經作者同意不得轉載,謝謝配合!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM