MongoDB如何在30小时前,48小时前和一个月前获得记录数?

时间:2017-04-13 07:12:42

标签: mongodb mongodb-query aggregation-framework loopback

我有以下结构:

{
   "_id" : ObjectId("58d8bcf01caf4ebddb842855"),
   "publishDate" : ISODate("2017-03-14T00:00:00.000Z")
},
{
   "_id" : ObjectId("58e87ed516b51f33ded59eb3"),
   "publishDate" : ISODate("2017-04-14T00:00:00.000Z")
},
{
   "_id" : ObjectId("58eb5b01c21fbad780bc74b6"),
   "publishDate" : ISODate("2017-04-09T00:00:00.000Z")
},
{
   "_id" : ObjectId("58eb5b01c21fbad780bc74b9"),
   "publishDate" : ISODate("2017-04-12T00:00:00.000Z")
}

现在我要计算一个月前发布的记录数,48小时前发布的记录数,以及30小时前发布的记录数。

我目前的尝试是:

db.JobPosting.aggregate([
   {$project:{
      "thirtyDaysAgo":{"publishDate":{$lt:["$publishDate",new Date(ISODate().getTime() - 1000*60*60*24*30)]}}, 
      "fourtyEightHourAgo":{"publishDate":{$lt:["$publishDate",new Date(ISODate().getTime() - 1000*60*60*48)]}}, 
      "thirtyHourAgo":{"publishDate":{$lt:["$publishDate",new Date(ISODate().getTime() - 1000*60*60*30)]}}
  }}, 
  {$group:{
      _id:{thirtyDaysAgo:"$thirtyDaysAgo", fourtyEightHourAgo:"$fourtyEightHourAgo", thirtyHourAgo:"$thirtyHourAgo"}, 
      "count":{$sum:1}
  }}
])

但结果是错误的:

{ "_id" : { "thirtyDaysAgo" : { "publishDate" : false }, "fourtyEightHourAgo" : { "publishDate" : true }, "thirtyHourAgo" : { "publishDate" : true } }, "count" : 1 }
{ "_id" : { "thirtyDaysAgo" : { "publishDate" : false }, "fourtyEightHourAgo" : { "publishDate" : false }, "thirtyHourAgo" : { "publishDate" : false } }, "count" : 1 }
{ "_id" : { "thirtyDaysAgo" : { "publishDate" : true }, "fourtyEightHourAgo" : { "publishDate" : true }, "thirtyHourAgo" : { "publishDate" : true } }, "count" : 1 }

我想要的是: {moreThanThirtyDayAgo:{count:1}, moreThanFourtyEightHourAgo:{count:2}, moreThanThirtyHourAgo:{count:1}}

1 个答案:

答案 0 :(得分:2)

使用 $cond 条件表达式创建一个二元决策树,将评估结果提供给 $sum 累加器。以下面的管道为例:

var dateThirtyHoursAgo = new Date();
dateThirtyHoursAgo.setHours(dateThirtyHoursAgo.getHours()-30);

var dateFourtyEightHoursAgo = new Date();
dateFourtyEightHoursAgo.setHours(dateFourtyEightHoursAgo.getHours()-48);

var dateMonthAgo = new Date();
dateMonthAgo.setMonth(dateMonthAgo.getMonth()-1);

var pipeline = [
    {
        "$group": {
            "_id": null,
            "thirtyHourAgo": {
                "$sum": {
                    "$cond": [ 
                        { "$gte": [ "$publishDate", dateThirtyHoursAgo ] }, 
                        1, 0 
                    ]
                }
            },
            "fourtyEightHourAgo": {
                "$sum": {
                    "$cond": [ 
                        { "$gte": [ "$publishDate", dateFourtyEightHoursAgo ] }, 
                        1, 0 
                    ]
                }
            },
            "thirtyDaysAgo": {
                "$sum": {
                    "$cond": [ 
                        { "$gte": [ "$publishDate", dateMonthAgo ] }, 
                        1, 0 
                    ]
                }
            }
        }
    }
];

db.JobPosting.aggregate(pipeline);