Reputation: 2757
Using mongodb
via mongoose
in my node.js
project.
My documents have the following structure:
{ created: new Date("2014-12-24"), last_visited: new Date("2014-12-24") },
{ created: new Date("2014-12-16"), last_visited: new Date("2014-12-24") },
{ created: new Date("2014-12-13"), last_visited: new Date("2014-12-13") },
{ created: new Date("2014-12-12"), last_visited: new Date("2014-12-20") },
{ created: new Date("2010-01-01"), last_visited: new Date("2014-12-20") }
I want to display how many documents were created/updated at certain date in the last 30 days. So the output should be like:
{ date: ISODate("2014-12-12"), created: 2, last_visited: 0 },
{ date: ISODate("2014-12-13"), created: 1, last_visited: 0 },
{ date: ISODate("2014-12-16"), created: 1, last_visited: 0 },
{ date: ISODate("2014-12-20"), created: 0, last_visited: 2 },
{ date: ISODate("2014-12-22"), created: 0, last_visited: 1 },
{ date: ISODate("2014-12-24"), created: 0, last_visited: 2 },
Notice that year 2010 entry was skipped due to it is older that 30 days.
How can I do that?
Upvotes: 0
Views: 125
Reputation: 2083
Try this
db.users.aggregate([
{$group: {
"_id": {
month: {$month: "$created"},
day: {$dayOfMonth: "$created"},
year: {$year: "$created"},
},
date: {$max: '$created'},
created: {$sum: 1},
last_visited: {$sum: 1},
}},
{$sort: {
'date': -1
}}
])
Thanks
Upvotes: 1
Reputation: 6371
A map reduce problem:
var old = new Date();
old.setDate(old.getDate()-30);
var filter = { created : {$gt : old}, last_visited : {$gt : old} };
var map = function()
{
emit(this.created, {created : 1, last_visited : 0 });
emit(this.last_visited, {created : 0, last_visited : 1 });
}
var reduce = function(key, values)
{
var out = {created : 0, last_visited : 0 };
for(i in values)
{
var value = values[i];
if(value.created != 0)
{
out.created++;
}
else
{
out.last_visited++;
}
}
return out;
}
db.runCommand(
{
mapReduce: "test2",
map: map,
reduce: reduce,
out: { "inline": 1 },
query: filter
}
).results
Upvotes: 1