2015-10-27 66 views
1

我有一個簡單集合,僅僅通過狀態返回一定時間幀之間的用戶的總和。MongoDB的骨料包括僞數據

User.aggregate([ 
    { 
    $match: { 
     "created" : { 
      $gt: startDate, 
      $lt: endDate 
     } 
    } 
    }, 
    { 
    $group: { 
     "_id": "$status", 
     "count" : { 
     $sum: 1 
     } 
    } 
    } 
]) 

我想要做的是在日期範圍內顯示每天的數據,即使沒有數據。

因此,舉例來說,結果可能最終會是這樣的:

[{ 
'_id' : '01-15-2015', 
    status_counts: { 
    'active': 15, 
    'inactive': 25, 
    'removed': 2 
    } 
}, 
{ 
'_id' : '01-16-2015', 
    status_counts: { 
    'active': 0, 
    'inactive': 0, 
    'removed': 0 
    } 
}, 
{ 
'_id' : '01-17-2015', 
    status_counts: { 
    'active': 25, 
    'inactive': 5, 
    'removed': 1 
    } 
}] 

任何想法我怎麼會去這樣做?基本上總結所有狀態並按天分組,但如果沒有數據存在,請將默認數據清零?

示例數據:

[{ 
    "_id" : ObjectId("55413bc29d41675785bf7ed2"), 
    "status" : "active", 
    "created" : ISODate("2015-10-11T17:25:46.843Z") 
}, 
{ 
    "_id" : ObjectId("55413bc29d41675785bf7ed2"), 
    "status" : "inactive", 
    "created" : ISODate("2015-10-12T17:25:46.843Z") 
}, 
{ 
    "_id" : ObjectId("55413bc29d41675785bf7ed2"), 
    "status" : "removed", 
    "created" : ISODate("2015-10-12T17:25:46.843Z") 
}, 
{ 
    "_id" : ObjectId("55413bc29d41675785bf7ed2"), 
    "status" : "active", 
    "created" : ISODate("2015-10-14T17:25:46.843Z") 
}, 
{ 
    "_id" : ObjectId("55413bc29d41675785bf7ed2"), 
    "status" : "active", 
    "created" : ISODate("2015-10-14T17:25:46.843Z") 
}, 
{ 
    "_id" : ObjectId("55413bc29d41675785bf7ed2"), 
    "status" : "active", 
    "created" : ISODate("2015-10-17T17:25:46.843Z") 
}] 

結果舉例:

[{ 
    "_id":"10-11-2015", 
    "status_counts": { 
     "active":1, 
     "inactive":0, 
     "removed":0 
    } 
}, 
{ 
    "_id":"10-12-2015", 
    "status_counts": { 
     "active":0, 
     "inactive":1, 
     "removed":1 
    } 
}, 
{ 
    "_id":"10-13-2015", 
    "status_counts": { 
     "active":0, 
     "inactive":0, 
     "removed":0 
    } 
}, 
{ 
    "_id":"10-14-2015", 
    "status_counts": { 
     "active":2, 
     "inactive":0, 
     "removed":0 
    } 
}, 
{ 
    "_id":"10-15-2015", 
    "status_counts": { 
     "active":0, 
     "inactive":0, 
     "removed":0 
    } 
}, 
{ 
    "_id":"10-16-2015", 
    "status_counts": { 
     "active":0, 
     "inactive":0, 
     "removed":0 
    } 
}, 
{ 
    "_id":"10-17-2015", 
    "status_counts": { 
     "active":1, 
     "inactive":0, 
     "removed":0 
    } 
}] 

回答

1

使用下面的管道,其中管道在$project階段,即由每月僅由一個新的屬性創建一個文檔天的年使用date aggregation operatorsstring operators$concat$subtr運營商做的字符串操作。然後,您可以使用新的屬性在前面$group流水線工序組密鑰,並通過使用$cond運營商能夠評估狀態的類型和值分配給$sum獲得相應的狀態計數。閉幕$project流水線階段則重塑的最後文件的子文檔內提供所需的字段:

User.aggregate([ 
    { 
     "$match": { 
      "created": { "$gt": startDate, "$lt": endDate } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, "status": 1, 
      "dayPart": { 
       "$concat" : [ 
        { 
         "$substr": [ {"$month" : "$created"}, 0, 2 ] 
        }, "-", 
        { 
         "$substr": [ {"$dayOfMonth" : "$created"}, 0, 2 ] 
        }, "-", 
        { 
         "$substr": [ {"$year" : "$created"}, 0, 4 ] 
        } 
       ] 
      } 
     } 
    }, 
    { 
     "$group": { 
      "_id": "$dayPart",    
      "active_count": { 
       "$sum": { 
        "$cond": [ { "$eq": [ "$status", "active" ] }, 1, 0 ] 
       } 
      }, 
      "inactive_count": { 
       "$sum": { 
        "$cond": [ { "$eq": [ "$status", "inactive" ] }, 1, 0 ] 
       } 
      }, 
      "removed_count": { 
       "$sum": { 
        "$cond": [ { "$eq": [ "$status", "removed" ] }, 1, 0 ] 
       } 
      }    
     } 
    }, 
    { 
     "$project": {    
      "status_counts": { 
       "active": "$active_count", 
       "inactive": "$inactive_count", 
       "removed": "$removed_count" 
      } 
     } 
    } 
]) 
+0

這是真棒!有一件事,如果它沒有提供任何一天的記錄,它不會返回任何內容。無論如何,包括沒有任何數據的一天? – dzm

+0

謝謝,只是添加了一些示例數據和示例結果 – dzm