MongoDB计算日期分组的计数

时间:2015-12-21 12:43:08

标签: mongodb date mongodb-query aggregation-framework

我想通过在 assigned_on 上使用分组来计算每天的分配数量。我可以获得每天的分配计数,但这些是唯一计数每一天。

在那个计数中,我还希望包括昨天或前几天但尚未发布的床位。

例如,我有以下记录

{
    "assigned_on":ISODate("2015-12-01T00:00:00Z"),
    "released_on":ISODate("2015-12-01T14:01:23Z"),
    "bed_id":1
},

{
    "assigned_on":ISODate("2015-12-01T00:00:00Z"),
    "released_on":ISODate("2015-12-04T14:01:23Z"),
    "bed_id":2
},

{
    "assigned_on":ISODate("2015-12-01T00:00:00Z"),
    "released_on":ISODate("2015-12-01T14:01:23Z"),
    "bed_id":3
},

{
    "assigned_on":ISODate("2015-12-02T00:00:00Z"),
    "released_on":ISODate("2015-12-02T14:01:23Z"),
    "bed_id":1
},


{
    "assigned_on":ISODate("2015-12-02T00:00:00Z"),
    "released_on":ISODate("2015-12-02T14:01:23Z"),
    "bed_id":3
},

{
    "assigned_on":ISODate("2015-12-03T00:00:00Z"),
    "released_on":ISODate("2015-12-03T14:01:23Z"),
    "bed_id":1
},


{
    "assigned_on":ISODate("2015-12-03T00:00:00Z"),
    "released_on":ISODate("2015-12-03T14:01:23Z"),
    "bed_id":3
}

当前查询

 db.test.aggregate([
      {
        "$match": {
          "assigned_on": {
            "$gte": ISODate("2015-12-01T00:00:00Z"),
            "$lt": ISODate("2015-12-03T23:59:59Z")
          }
        }
      },
      {
        "$group": {
          "_id": {
            "$dayOfMonth": "$assigned_on"
          },
          "Count": {
            "$sum": 1
          }
        }
      }
    ])

通过分配给assign_on我得到了第1,2和3天的结果,但是我希望第1,2天和第3天的计数在结果中分别为3,因为在第二天记录已发布日期是12月4日,这意味着床2在第1,2,3和4天被占用。

当前输出:

{ "_id" : 3, "Count" : 2 }
{ "_id" : 2, "Count" : 2 }
{ "_id" : 1, "Count" : 3 }

预期产出:

{ "_id" : 3, "Count" : 3 }
{ "_id" : 2, "Count" : 3 }
{ "_id" : 1, "Count" : 3 }

编辑:_id是12月1日,12月2日和12月3日的日期,数量是相应日期分配的床位数

帮助或指针非常有用

1 个答案:

答案 0 :(得分:2)

你可以使用mongodb mapReduce

来完成
var map = function(){

    var startDate = new Date(this.assigned_on.getTime());
    //set time to midnight
    startDate.setHours(0,0,0,0);

    //foreach date in date range [assigned_on, released_on) emit date with value(count) 1 
    for (var date = startDate; date < this.released_on; date.setDate(date.getDate() + 1)) {
        if(this.bed_id) {
            emit(date, 1);
        }
    }
};

//calculate total count foreach emitted date(key) 
var reduce = function(key, values){
    return Array.sum(values)
};

db.collection.mapReduce(map, reduce, {out : {inline : 1}}, callback);

对于您的数据,我得到了这样的结果:

[ { _id: Tue Dec 01 2015 02:00:00 GMT+0200 (EET), value: 3 },
  { _id: Wed Dec 02 2015 02:00:00 GMT+0200 (EET), value: 3 },
  { _id: Thu Dec 03 2015 02:00:00 GMT+0200 (EET), value: 3 },
  { _id: Fri Dec 04 2015 02:00:00 GMT+0200 (EET), value: 1 } ]