As you've noticed, the Aggregation Framework (as at MongoDB 2.4) has operators to extract parts of dates but not to easily create date fields.
There's a great blog post on Stupid date tricks with Aggregation Framework that provides a creative workaround: truncate the date granularity using $project
before you $group
:
db.Twitter_Processed.aggregate(
// Match (can take advantage of suitable index)
{ $match : {
"_id.SpId" : 840,
"_id.Scheduler_Id" : 1
}},
// Extract h/m/s/ms values from PostDate for rounding
{ $project: {
SpId : "$_id.SpId",
Scheduler_Id : "$_id.Scheduler_Id",
PostDate : "$PostDate",
h : { "$hour" : "$PostDate" },
m : { "$minute" : "$PostDate" },
s : { "$second" : "$PostDate" },
ms : { "$millisecond" : "$PostDate" },
senti : "$Sentiment"
}},
// Subtract the h/m/s/ms values to round the date off to yyyy-mm-dd
{ $project: {
SpId : "$_id.SpId",
Scheduler_Id : "$_id.Scheduler_Id",
// PostDate will end up truncated to yyyy-mm-dd granularity
PostDate: {
"$subtract" : [
"$PostDate",
{
"$add" : [
"$ms",
{ "$multiply" : [ "$s", 1000 ] },
{ "$multiply" : [ "$m", 60, 1000 ] },
{ "$multiply" : [ "$h", 60, 60, 1000 ]}
]
}
]
},
senti: "$Sentiment"
}},
{ $group : {
_id : {
SpId : "$SpId",
Scheduler_Id : "$Scheduler_Id",
PostDate: "$PostDate"
},
sentiment : { $sum : "$senti"}
}},
{ $group : {
_id : "$_id" ,
avgSentiment : {$avg : "$sentiment"}
}}
)