【问题标题】:sum of daily activities over a month of July MongoDB aggregate7 月份 MongoDB 聚合中的每日活动总和
【发布时间】:2021-01-06 21:05:07
【问题描述】:

我需要计算 7 月份每天完成的步数。我期待 31 个结果。

这是来自数据库的示例:

/* 1 */
{
    "_id" : ObjectId("5ff0a5878da39cdbf696ffea"),
    "dateTime" : ISODate("2020-07-03T17:20:00.000Z"),
    "value" : "14"
}

/* 2 */
{
    "_id" : ObjectId("5ff0a5878da39cdbf696ffeb"),
    "dateTime" : ISODate("2020-07-03T17:43:00.000Z"),
    "value" : "57"
}

“价值”是完成的步骤。

【问题讨论】:

  • 请不要提供图片,使用格式化文本作为示例数据,对于您尝试过的和预期的结果。
  • “每天 31 个结果”是什么意思?
  • 因为七月有 31 天的伙伴。问题是,7 月份每天完成的步骤数。
  • 每天的步数(n.b. 什么是“步”)与每月的天数有什么关系?
  • "dateTime" : ISODate("2020-07-03T17:43:00.000Z"), "value" : "57" 这意味着这个人在给定的日期和时间已经走了 57 步。所以我需要得到他在七月份每天所做的步骤的总和。所以从技术上讲,我需要找到第 1 天:100 步......第 2 天:150 步......等整个月。

标签: mongodb nosql nosql-aggregation


【解决方案1】:

如果您想在 JS 帮助下获得 0 天计数,这里是一个解决方案(您需要在 jsMonth 中提供哪个月份,在 jsDayCount 中提供哪一年):

mongos> db.d.find()
{ "_id" : ObjectId("5ff62e4484088fbb4acaf035"), "dateTime" : ISODate("2020-07-03T17:20:00Z"), "value" : "14" }
{ "_id" : ObjectId("5ff62e4484088fbb4acaf036"), "dateTime" : ISODate("2020-07-05T17:20:00Z"), "value" : "14" }
{ "_id" : ObjectId("5ff62e4484088fbb4acaf037"), "dateTime" : ISODate("2020-07-03T17:20:00Z"), "value" : "50" }
{ "_id" : ObjectId("5ff62e4484088fbb4acaf038"), "dateTime" : ISODate("2020-08-10T17:20:00Z"), "value" : "100" }
mongos> var jsMonth=7;var jsDayCount=new Date(2020, jsMonth , 0).getDate();
mongos> db.d.aggregate([ 
{$project:{ byDay:{$dayOfMonth:{date:"$dateTime",timezone:"+0200"}},_id:0 , val:{$toInt:"$value"} ,mon: {$month:{date:'$dateTime',timezone:"+0200"}}  }} ,{$match:{ mon:jsMonth   }}  ,
{$group:{_id:"$byDay" , perDayTotal:{$sum:"$val"}}}    , {$sort:{_id:1}}  , 
{$group:{_id:"total" , arr:{$push:{day:"$_id",perDay:"$perDayTotal"   }} }}  , 
{ $addFields:{ arr:{ $reduce:{ input:{$setDifference:[ {$range:[1,jsDayCount,1]} ,"$arr.day"  ]   }, initialValue:"$arr",in:{ $concatArrays: 
["$$value" ,[{day:"$$this", perDay:0  }] ]     }     }  }  } }   ,
{$unwind:"$arr"}, 
{$project:{_id:0 ,day:"$arr.day" ,    countPerDay:"$arr.perDay"}}   , $sort:{"day":1}} ])
{ "day" : 1, "countPerDay" : 0 }
{ "day" : 2, "countPerDay" : 0 }
{ "day" : 3, "countPerDay" : 64 }
{ "day" : 4, "countPerDay" : 0 }
{ "day" : 5, "countPerDay" : 14 }
{ "day" : 6, "countPerDay" : 0 }
{ "day" : 7, "countPerDay" : 0 }
{ "day" : 8, "countPerDay" : 0 }
{ "day" : 9, "countPerDay" : 0 }
{ "day" : 10, "countPerDay" : 0 }
{ "day" : 11, "countPerDay" : 0 }
{ "day" : 12, "countPerDay" : 0 }
{ "day" : 13, "countPerDay" : 0 }
{ "day" : 14, "countPerDay" : 0 }
{ "day" : 15, "countPerDay" : 0 }
{ "day" : 16, "countPerDay" : 0 }
{ "day" : 17, "countPerDay" : 0 }
{ "day" : 18, "countPerDay" : 0 }
{ "day" : 19, "countPerDay" : 0 }
{ "day" : 20, "countPerDay" : 0 }
{ "day" : 21, "countPerDay" : 0 }
{ "day" : 22, "countPerDay" : 0 }
{ "day" : 23, "countPerDay" : 0 }
{ "day" : 24, "countPerDay" : 0 }
{ "day" : 25, "countPerDay" : 0 }
{ "day" : 26, "countPerDay" : 0 }
{ "day" : 27, "countPerDay" : 0 }
{ "day" : 28, "countPerDay" : 0 }
{ "day" : 29, "countPerDay" : 0 }
{ "day" : 30, "countPerDay" : 0 }
mongos> 

【讨论】:

    【解决方案2】:

    根据要求,也许这样的事情可以完成:

    db.the_steps_collection.aggregate([ {$project:{ byDay:{$substr:["$dateTime",0,10]},_id:0 , val:{$toInt:"$value"}   }} ,{$match:{ byDay:/^2020-07/   }}  , {$group:{_id:"$byDay" , perDayTotal:{$sum:"$val"}}}   ])
    

    或者这似乎更快:

    db.the_steps_collection.aggregate([ {$project:{ byDay:{$substr:["$dateTime",0,10]},_id:0 , val:{$toInt:"$value"} ,mon:{$month: '$dateTime'}  }} ,{$match:{ mon:7   }}  , {$group:{_id:"$byDay" , perDayTotal:{$sum:"$val"}}}   ])
    

    更干净(时区可能不同):

    db.the_steps_collection.aggregate([ {$project:{ byDay:{$dayOfMonth:{date:"$dateTime",timezone:"+0200"}},_id:0 , val:{$toInt:"$value"} ,mon:{$month:{date:'$dateTime',timezone:"+0200"}}  }} ,{$match:{ mon:7   }}  , {$group:{_id:"$byDay" , perDayTotal:{$sum:"$val"}}}  ,{$sort:{_id:1}} ])
    

    【讨论】:

    • 不客气! (如果您接受解决方案,请添加绿色复选框;))
    • 有没有办法对结果进行排序? :)
    • 将 $sort 阶段按 dayOfMonth 添加到最新... :)
    • 你是明星@kiki0075....谢谢。但我不能投票,因为我的声望低于 15
    • 啊,不用担心,不知道声誉低时您不能接受答案...
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 2013-12-31
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多