Mongoose provides a lightweight wrapper around the MongoDB aggregation framework. If you're new to aggregation, you can learn more about in from the MongoDB docs: http://docs.mongodb.org/manual/aggregation/
To massage your data into the form you've described above, you can use an aggregation pipeline with a series of $group operations. Here it is using the mongoose framework:
var dateSchema = mongoose.Schema({…});
var DateItem = mongoose.model('DateItem', dateSchema);
DateItem.aggregate(
{ $group : {
_id : { year: { $year : "$accessDate" }, month: { $month : "$accessDate" },day: { $dayOfMonth : "$accessDate" }},
count : { $sum : 1 }}
},
{ $group : {
_id : { year: "$_id.year", month: "$_id.month" },
dailyusage: { $push: { day: "$_id.day", count: "$count" }}}
},
{ $group : {
_id : { year: "$_id.year" },
monthlyusage: { $push: { month: "$_id.month", dailyusage: "$dailyusage" }}}
},
function (err, res)
{ if (err) ; // TODO handle error
console.log(res);
});
});
The first $group will result in documents of this form, one for each day:
{
"_id" : { "year" : 2013, "month" : 8, "day" : 15 },
"count" : 1
}
The second $group will result in documents grouped by month:
{
"_id" : { "year" : 2012, "month" : 11 },
"dailyusage" : [
{ "day" : 6, "count" : 1 },
{ "day" : 9, "count" : 1 },
... ]
},
And the third $group will result in even larger documents, one for each year.
This query will aggregate your data into large, hierarchical documents. If you plan to run queries on this data after aggregation, however, this might not be the most useful form for your data to be in. Consider how you'll be using the aggregated data. A schema involving more smaller documents, perhaps one per month or even one per day, might be more convenient.