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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With