MongoDB Aggregation: How do I recombine a date using $project?
mongodb, mongoose
Solution
Assuming that, as you are grouping documents by year, month and day, hours and minutes are useless, you can use one of those operators to get a date sample: `$first`, `$last`, `$min` or `$max`.
Sentiment.aggregate([
{
$match: { 'content.term' : term_id }
}, {
$group: {
_id: {
year : { $year : '$created_at' },
month : { $month : '$created_at' },
dayOfMonth : { $dayOfMonth : '$created_at' },
},
dt_sample : { $first : '$created_at' },
sum : { $sum : '$score'},
count : { $sum : 1 }
},
}, {
$project: {
_id : 0,
date : '$dt_sample',
sum : 1,
count : 1,
avg : { $divide: ['$sum', '$count'] }
}
}
], function(err, result){
if(err) callback(err);
else callback(null, result);
});
You'll have a date field with an arbitrary hour, minute and seconds.
Problem
I'm trying to aggregate my data by day so I can render it in a chart. I've managed to do this successfully by grouping by `$year`, `$month`, and `$dayOfMonth`. However, that means that my date is now split into three parts in the final result. Is there a way to concat the three numbers back into a date format or is there another way to group by day that doesn't split date? Below is a working example of what I have: ``` Sentiment.aggregate([ { $match: { 'content.term' : term_id } }, { $group: { _id: { year : { $year : '$created_at' }, month : { $month : '$created_at' }, dayOfMonth : { $dayOfMonth : '$created_at' }, }, sum : { $sum : '$score'}, count : { $sum : 1 } }, }, { $project: { _id : 0, date : '$_id', sum : 1, count : 1, avg : { $divide: ['$sum', '$count'] } } } ], function(err, result){ if(err) callback(err); else callback(null, result); }); ``` And here is a sample result: ``` [ { "sum": 201, "count": 3, "date": { "year": 2013, "month": 7, "dayOfMonth": 5 }, "avg": 67 }, { "sum": 186, "count": 6, "date": { "year": 2013, "month": 7, "dayOfMonth": 8 }, "avg": 31 }, { "sum": 834, "count": 9, "date": { "year": 2013, "month": 7, "dayOfMonth": 9 }, "avg": 92.66666666666667 } ] ``` Ideally, I'd like to have `date` be a valid date so I don't have to convert it later. I've tried using `$concat` but that only works with strings. I am using `Mongoose` if that makes a difference.