Use one MongoDB group() query to make an array of sums for each day of the month
I've created a MongoDB aggregation query that will give me the sum of data for the current month, but how could I modify this so that it would return an array from each day of the month, with the total for each day (I assume this is possible, but I'm finding it difficult to get it working)? If this isn't possible, is there a better way of doing this than using a loop and running 30 group queries?
I'm using the PHP driver, but an answer in shell is just as useful.
$total_this_month = $db->test->group(
array( ),
array(
'sum' => 0
),
new MongoCode( 'function(doc, out){ out.sum += doc.data; }' ),
array(
开发者_如何学JAVA 'condition' => array(
'time' => array(
'$gte' => new MongoDate(strtotime('first day of this month, 00:00:00')),
'$lte' => new MongoDate(strtotime('last day of this month, 23:59:59'))
)
)
)
);
If you plan on running your group query often you should consider adding a new field or fields that allow you to group by the time period you need. The previous answer of using map-reduce is a great one if this is an ad-hoc query that doesn't need performance tuning. For example, I have a collection that needs to be aggregated sometimes by day, week, month, etc. Here is an example record:
{"_id" : ObjectId("4ddaed3a8b0f766963000003"),
"name": "Sample Data",
"time" : "Mon May 23 2011 17:26:50 GMT-0600 (MDT)",
"period" : {
"m" : 201105,
"w" : 201121,
"d" : 20110523,
"h" : 2011052317
}
}
With these additional fields I can do a lot more with the group function and can also index those fields for faster queries. You can choose to use integers, as I did, or strings - either way will work, but remember that your query parameters need to be of the same data type. I like integers because it seems that they should perform a little better and use less space (just a hunch).
The group command doesn't support generating new grouping keys via a function, so use map/reduce instead of group.
精彩评论