Reputation: 9958
I am trying to aggregate using time buckets. Then, I want to return an array full of the values per day (0 when no document found). The aggeagate function work wondefully, but when I replace the callback (formerly console.log) like this:
Star.aggregate([{
$match: {
"mod": new mongoose.Types.ObjectId("53765a122c0cda28199df3f4"),
"time_bucket.month": new TimeBucket().month
}
},
{
$group: {
_id: "$time_bucket.day",
stars: {
"$sum": 1
}
}
},
{
$sort: {
'_id': 1
}
}],
function (err, mods) {
console.log(err, mods);
mods = mods.map(function (model) {
return model.toObject ? model.toObject() : model
});
var i, time, docs = [];
var hasGap = function (a, b) {
a = a.replace(/-/g, '');
b = b.replace(/-/g, '');
return a - b !== 1
}
var process = function (i, mods, docs) {
if (hasGap(mods[i]._id, mods[i + 1]._id)) {
docs.push(0);
return process(i, mods, docs)
}
docs.push(mods[i].stars);
return process(i + 1, mods, docs)
};
process(0, mods, docs);
console.log(docs);
});
I get:
C:\Users\Me\Nodejs\node_modules\mongoose\node_modules\mongodb\lib\mongodb\connection\base.js:245
throw message;
^
RangeError: Maximum call stack size exceeded
Upvotes: 2
Views: 3208
Reputation: 312095
Your process
function is recursive and has no path that breaks the recursion by not calling process
again. A classic infinite recursion stack overflow.
The solution is to change the process
function so that it checks for being at the end of the mods
array of result docs and then simply return at that point instead of calling itself again.
So a check like:
if (i >= mods.length) return;
Upvotes: 2