MongoDB aggregate include pseudo data -
i have simple aggregate returns sum of users status between time frame.
user.aggregate([ { $match: { "created" : { $gt: startdate, $lt: enddate } } }, { $group: { "_id": "$status", "count" : { $sum: 1 } } } ])
what display data every day within date range, if there no data.
so example, result may end this:
[{ '_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 } }]
any ideas how go doing this? summing statuses , grouped day, if no data there, include default data zeroed out?
example data:
[{ "_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") }]
example result:
[{ "_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 } }]
use following pipeline pipeline $project
stage creates document new property composed month-day-year using date aggregation operators , string operators $concat
, $subtr
operators string manipulation. can use new property in preceding $group
pipeline step group key , obtain respective status counts using $cond
operator evaluate status type , assign value $sum
. closing $project
pipeline stage reshapes final documents provide needed fields within subdocument:
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" } } } ])
Comments
Post a Comment