欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MongoDB按時(shí)間分組操作實(shí)戰(zhàn)

 更新時(shí)間:2023年05月25日 09:30:26   作者:愧怍12  
MongoDB支持使用聚合操作來統(tǒng)計(jì)數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于MongoDB按時(shí)間分組操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

需求

需求是這樣的,要統(tǒng)計(jì)每一周的各個(gè)商品的銷售記錄,使用 echarts 圖表呈現(xiàn),如下圖

image-20210830214556262

說實(shí)話,一開始聽到這個(gè)需求的時(shí)候,我是有點(diǎn)慌的,因?yàn)?MongoDB 的分組玩的比較少(Mysql 也差不多),又要按照對(duì)應(yīng)的星期來進(jìn)行分組,這在之前學(xué)習(xí) MongoDB 的時(shí)候還沒接觸過,于是就準(zhǔn)備寫了這篇文章,來記錄下我是如何進(jìn)行分組的

MongoDB 的一些時(shí)間操作符

時(shí)間操作符(專業(yè)術(shù)語應(yīng)該不是這個(gè),后文暫且使用這個(gè)來描述),后面會(huì)用到的

  •  $dayOfYear: 返回該日期是這一年的第幾天。(全年366天)
  •  $dayOfMonth: 返回該日期是這一個(gè)月的第幾天。(1到31)
  •  $dayOfWeek: 返回的是這個(gè)周的星期幾。(1:星期日,7:星期六)
  •  $year: 返回該日期的年份部分
  •  $month: 返回該日期的月份部分(between 1 and 12.)
  •  $week: 返回該日期是所在年的第幾個(gè)星期(between 0 and 53)
  •  $hour: 返回該日期的小時(shí)部分
  •  $minute: 返回該日期的分鐘部分
  •  $second: 返回該日期的秒部分(以0到59之間的數(shù)字形式返回日期的第二部分,但可以是60來計(jì)算閏秒。)
  •  $millisecond:返回該日期的毫秒部分(between 0 and 999.)
  •  $dateToString:{ $dateToString: { format: <formatString>, date: <dateExpression> } }

日期分組

mongdb 聚合查詢?nèi)掌?統(tǒng)計(jì)每天數(shù)據(jù)

db.getCollection('Br-Special').aggregate(  
    [     
        {   $project : { day : {$substr: ["$datetime", 0, 10] }}},          
        {   $group   : { _id : "$day",  number : { $sum : 1 }}},  
        {   $sort    : { _id : -1 }}          
    ]  
)

result:

關(guān)于日期分組的話,我是借鑒了上面的,也確實(shí)帶我解惑了下如何按照日期分組。這里貼下我的代碼

 let list = await this.goodsModel
   .aggregate([
     { $project: { date: { $dateToString: ['$created_at', 0, 10] } } },
     { $group: { _id: '$date', count: { $sum: 1 } } },
     { $project: { date: '$_id', _id: 0, count: 1 } }, // 再使用$project將_id改名為date
     { $sort: { date: -1 } }, // 根據(jù)日期倒序
   ])
   .exec();

或者使用時(shí)間操作符(更準(zhǔn)確一點(diǎn))

 let list = await this.goodsModel
   .aggregate([
     {
       $project: { date: { $dateToString: { format: '%Y-%m-%d', date: '$created_at' } } },
     },
     { $group: { _id: '$date', count: { $sum: 1 } } },
     { $project: { date: '$_id', _id: 0, count: 1 } }, // 再使用$project將_id改名為date
     { $sort: { date: -1 } }, // 根據(jù)日期倒序
   ])
   .exec();

通過

要注意的是,$group 里的屬性必須為_id,不然無法分組

獲取到的數(shù)據(jù)如下(這里只顯示一周)

 [
   { "count": 54, "date": "2021-08-30" },
   { "count": 29, "date": "2021-08-29" },
   { "count": 16, "date": "2021-08-28" },
   { "count": 17, "date": "2021-08-27" },
   { "count": 12, "date": "2021-08-26" },
   { "count": 6, "date": "2021-08-25" }
   // { "count": 0, "date": "2021-08-24" },
 ]

如果只是日期和總商品的話,上面就足以顯示對(duì)應(yīng)的數(shù)據(jù)了,可我要根據(jù)星期進(jìn)行分組的話,就需要替換 MongoDB 的時(shí)間轉(zhuǎn)化函數(shù)了

星期分組

星期分組的話,其實(shí)也挺簡單的,只需要把上面的

 $project: { day: { $dateToString: { format: "%Y-%m-%d", date: "$created_at" } } }

替換成

 $project: {
   week: {
     $dayOfWeek: {
       date: '$created_at';
     }
   }
 }

完整代碼如下

 // 要獲取的是一周前的零點(diǎn)時(shí)間
 let lastweekDay = dayjs(dayjs().add(-7, 'day').format('YYYY-MM-DD')).valueOf();
 ?
 let list = await this.goodsModel
   .aggregate([
     { $match: { created_at: { $gte: new Date(lastweekDay) } } }, //范圍時(shí)間
     { $project: { week: { $dayOfWeek: { date: '$created_at' } } } },
     { $group: { _id: '$week', count: { $sum: 1 } } },
     { $project: { week: '$_id', _id: 0, count: 1 } }, // 再使用$project將_id改名為week
     { $sort: { week: 1 } }, // 根據(jù)星期正序
   ])
   .exec();

獲取的結(jié)果如下

 [
   { count: 29, week: 1 }, // 星期七(日)
   { count: 54, week: 2 }, // 星期一
   { count: 1, week: 3 }, // 星期二
   { count: 9, week: 4 }, // 星期三
   { count: 12, week: 5 }, // 星期四
   { count: 17, week: 6 }, // 星期五
   { count: 16, week: 7 }, // 星期六
 ];

但是,細(xì)心的你可能會(huì)發(fā)現(xiàn),貌似數(shù)據(jù)對(duì)不上,注當(dāng)天時(shí)間為 2021-08-30,星期一

 [
   { "count": 54, "date": "2021-08-30" }, // 星期一
   { "count": 29, "date": "2021-08-29" }, // 星期七(日)
   { "count": 16, "date": "2021-08-28" }, // 星期六
   { "count": 17, "date": "2021-08-27" }, // 星期五
   { "count": 12, "date": "2021-08-26" }, // 星期四
   { "count": 9, "date": "2021-08-25" }, // 星期三
   { "count": 1, "date": "2021-08-24" } // 星期二
 ]

其實(shí)只需要把星期向后排序一位就行,因?yàn)樾瞧诒緛砭褪菍⑿瞧谌兆鳛榈谝惶斓?,至此,按照星期分組總商品就算完畢了。同理,要按照月份,年份,甚至小時(shí),分鐘,都可以直接利用時(shí)間操作符轉(zhuǎn)化時(shí)間來進(jìn)行分組。

多商品

上述只是獲取了總商品了,要細(xì)分為多個(gè)商品的話,就需要再次利用聚合函數(shù)來進(jìn)行分組了。

這里先演示分組多個(gè)商品先,就和正常分組一樣

 let list = await this.goodsModel.aggregate([
 { $group: { _id: "$type", count: { $sum: 1 } } },
 ]).exec()

結(jié)果如下(這里輸出_id,是因?yàn)闆]有進(jìn)行$project 改別名,商品所采用的是數(shù)字表示)

 [
   { "_id": 1, "count": 111 },
   { "_id": 2, "count": 18 },
   { "_id": 4, "count": 2 },
   { "_id": 3, "count": 16 }
 ]

可以看到統(tǒng)計(jì)的是直接是所有商品的總和。

但問題來了,怎么樣能分組星期的同時(shí),又對(duì)每個(gè)商品所在星期進(jìn)行分組,并且到底是優(yōu)先分組星期期呢,還是優(yōu)先分組商品呢,這讓我陷入深深的思考。

最終實(shí)現(xiàn)

首先,絕對(duì)不可能使用兩次$group,要么沒有星期分組,要么沒有商品分組,于是我就把思路放在$project$group內(nèi),看看內(nèi)部是否有其他方法可以實(shí)現(xiàn)。

其中$group可以將屬性添加為數(shù)組,注意 goods: { $push: "$goods" }

 let list = await this.goodsModel
   .aggregate([
     { $match: { created_at: { $gte: new Date(lastweekDay) } } },
     { $project: { week: { $dayOfWeek: { date: '$created_at' } }, goods: 1 } },
     { $group: { _id: '$week', goods: { $push: '$goods' } } },
     { $project: { week: '$_id', _id: 0, goods: 1 } },
     { $sort: { week: 1 } },
   ])
   .exec();

可得到的數(shù)據(jù)卻是這樣的

 [
   {
     "goods": [4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1],
     "week": 1
   },
   {
     "goods": [1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
     "week": 2
   },
   {
     "goods": [1],
     "week": 3
   },
   {
     "goods": [3, 3, 3, 3, 3, 3, 3, 3, 4],
     "week": 4
   },
   {
     "goods": [3, 1, 1, 1, 3, 4, 1, 1, 1, 1, 1, 1],
     "week": 5
   },
   {
     "goods": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1],
     "week": 6
   },
   {
     "goods": [4, 3, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1],
     "week": 7
   }
 ]

數(shù)據(jù)很接近了,如果我能把對(duì)應(yīng)的商品總和算起來就行了,但問題是怎么合起來。。。

待會(huì),goods 既然是數(shù)組的話,那我能不能$unwind全部展開,然后我再來一次聚合,說干就干!

 let list = await this.goodsModel
   .aggregate([
     { $match: { created_at: { $gte: new Date(lastweekDay) } } },
     { $project: { week: { $dayOfWeek: { date: '$created_at' } }, goods: 1 } },
     { $group: { _id: '$week', goods: { $push: '$goods' } } },
     { $project: { week: '$_id', _id: 0, goods: 1 } },
     { $sort: { week: 1 } },
     { $unwind: '$goods' },
   ])
   .exec();

得到的數(shù)據(jù)(省略一堆)

 [
   { "goods": 4, "week": 1 },
   { "goods": 4, "week": 1 },
   { "goods": 1, "week": 1 },
   { "goods": 1, "week": 1 },
   { "goods": 1, "week": 2 },
   { "goods": 1, "week": 3 },
   { "goods": 1, "week": 4 }
 ]

然后我就卡住了,因?yàn)槲覠o論如何都無法分組一個(gè)字段的時(shí)候,又加以限制條件,要么分組商品的時(shí)候,統(tǒng)計(jì)的是一周各商品總數(shù)據(jù),要么就是分組星期的時(shí)候,統(tǒng)計(jì)的是總的商品數(shù)據(jù)。在搜索大量資料后,查看官方一些文檔也未果,于是我決定自行寫一個(gè) js 函數(shù)來進(jìn)行排序(實(shí)在是折騰不動(dòng)了,能力有限 ??)

最終完整代碼

 let lastweekDay = dayjs(dayjs().add(-7, 'day').format('YYYY-MM-DD')).valueOf();
 ?
 let list = await this.goodsModel
   .aggregate([
     { $match: { created_at: { $gte: new Date(lastweekDay) } } },
     { $project: { week: { $dayOfWeek: { date: '$created_at' } }, goods: 1 } },
     { $group: { _id: '$week', goods: { $push: '$goods' } } },
     { $project: { week: '$_id', _id: 0, goods: 1 } },
     { $sort: { week: 1 } },
     // { $unwind: "$goods" },
   ])
   .exec();
 ?
 function getEleNums(data) {
   var map = {};
   data.forEach((e) => {
     if (map[e]) {
       map[e] += 1;
     } else {
       map[e] = 1;
     }
   });
   return map;
 }
 ?
 list = list.map((l) => {
   l.goods = getEleNums(l.goods);
   return l;
 });
 cosnole.log(list);

運(yùn)行后的 list 結(jié)果為

 [
   { "goods": { "1": 26, "4": 3 }, "week": 1 },
   { "goods": { "1": 53, "4": 3, "5": 1 }, "week": 2 },
   { "goods": { "1": 1 }, "week": 3 },
   { "goods": { "3": 8, "4": 1 }, "week": 4 },
   { "goods": { "1": 9, "3": 2, "4": 1 }, "week": 5 },
   { "goods": { "1": 15, "3": 2 }, "week": 6 },
   { "goods": { "1": 9, "3": 6, "4": 1 }, "week": 7 }
 ]

如果是要 goods為分組的話,只需要把上面聚合代碼中week和goods替換一下便可。

另一種實(shí)現(xiàn)方式

專門新建一個(gè)表,用于統(tǒng)計(jì)每天的銷售記錄,然后分組的時(shí)候就根據(jù)該表就行了,具體代碼就實(shí)現(xiàn)了,思路是挺簡單的,但是需要新建一個(gè)表,增加記錄的時(shí)候有需要增加代碼,如果業(yè)務(wù)復(fù)雜的話。。。

總結(jié)

到此這篇關(guān)于MongoDB按時(shí)間分組操作實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)MongoDB按時(shí)間分組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mongodb使用$bit方法更新字段的代碼詳解

    Mongodb使用$bit方法更新字段的代碼詳解

    Mongodb的UPDATE提供了各種各樣的方法,包括字段數(shù)值增加,數(shù)組更新等,本文介紹Mongodb使用$bit方法更新字段,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-06-06
  • 把MongoDB作為循環(huán)隊(duì)列的方法詳解

    把MongoDB作為循環(huán)隊(duì)列的方法詳解

    這篇文章主要給大家介紹了關(guān)于把MongoDB作為循環(huán)隊(duì)列的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • MongoDB Windows安裝服務(wù)方法與注意事項(xiàng)

    MongoDB Windows安裝服務(wù)方法與注意事項(xiàng)

    這篇文章主要介紹了MongoDB Windows安裝服務(wù)方法與注意事項(xiàng)的相關(guān)資料,MongoDB作為一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫,近兩年大受追捧。數(shù)據(jù)靈活的存取方式和高效的處理使得它廣泛用于互聯(lián)網(wǎng)應(yīng)用,需要的朋友可以參考下
    2016-12-12
  • Mongodb解決不能連接到服務(wù)器的錯(cuò)誤問題

    Mongodb解決不能連接到服務(wù)器的錯(cuò)誤問題

    這篇文章主要介紹了Mongodb解決不能連接到服務(wù)器的錯(cuò)誤問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Mongodb數(shù)據(jù)庫誤刪后的恢復(fù)方法(兩種)

    Mongodb數(shù)據(jù)庫誤刪后的恢復(fù)方法(兩種)

    本文給大家分享兩種方法來實(shí)現(xiàn)Mongodb數(shù)據(jù)庫誤刪后的恢復(fù),每種方法給大家介紹的都非常詳細(xì),需要的朋友參考下吧
    2018-08-08
  • Centos 7下Mongodb開機(jī)無法自啟動(dòng)的解決方法

    Centos 7下Mongodb開機(jī)無法自啟動(dòng)的解決方法

    這篇文章主要介紹了Centos 7下Mongodb開機(jī)無法自啟動(dòng)的解決方法,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • MongoDB4.0在windows10下的安裝與服務(wù)配置教程詳解

    MongoDB4.0在windows10下的安裝與服務(wù)配置教程詳解

    本文通過圖文并茂的形式給大家介紹了MongoDB4.0在windows10下的安裝與服務(wù)配置教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • 關(guān)于mongoDB的聚合操作_aggregate()歸納詳解

    關(guān)于mongoDB的聚合操作_aggregate()歸納詳解

    這篇文章主要介紹了關(guān)于mongoDB的聚合操作_aggregate()歸納詳解,關(guān)系是關(guān)聯(lián)關(guān)系的一種,是強(qiáng)的關(guān)聯(lián)關(guān)系,聚合是整體和個(gè)體之間的關(guān)系,聚合關(guān)系也是通過實(shí)例變量實(shí)現(xiàn)的。在聚合關(guān)系中,兩個(gè)類是處在不平等層次上的,一個(gè)代表整體,另一個(gè)代表部分,需要的朋友可以參考下
    2023-07-07
  • Ubuntu 14.04  安裝 MongoDB 及 PHP MongoDB Driver詳細(xì)介紹

    Ubuntu 14.04 安裝 MongoDB 及 PHP MongoDB Driver詳細(xì)介紹

    這篇文章主要介紹了Ubuntu 14.04 安裝 MongoDB 及 PHP MongoDB Driver詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 利用MongoDB中oplog機(jī)制實(shí)現(xiàn)準(zhǔn)實(shí)時(shí)數(shù)據(jù)的操作監(jiān)控

    利用MongoDB中oplog機(jī)制實(shí)現(xiàn)準(zhǔn)實(shí)時(shí)數(shù)據(jù)的操作監(jiān)控

    MongoDB 的Replication是通過一個(gè)日志來存儲(chǔ)寫操作的,這個(gè)日志就叫做oplog,而下面這篇文章主要給大家介紹了利用MongoDB中oplog機(jī)制實(shí)現(xiàn)準(zhǔn)實(shí)時(shí)數(shù)據(jù)的操作監(jiān)控的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-05-05

最新評(píng)論