Mongoose - RangeError: Maximum Call Stack Size Exceeded
Confirmed, but not a bug. Model.collection.insert()
bypasses Mongoose and so you're telling the node driver to insert an object that contains mongoose internals like $__
, etc. The stack overflow is probably because bson is trying to compute the size of an object that references itself indirectly.
Long story short, use Document.toObject()
, that's what its for: http://mongoosejs.com/docs/api.html#document_Document-toObject
Response.find({}).exec(function(err, responses) {
if (err) {
return callback(err);
}
if (true) {
var toInsert = [];
responses.forEach(function(response) {
console.log("Filling response: " + response._id);
response.answers = [];
[{ name: 'test' }].forEach(function(ans) {
response.answers.push(ans);
});
toInsert.push(response.toObject());
});
Response.collection.insert(toInsert, function(err, responsesResult) {
console.log(err);
});
} else {
callback();
}
});
Also, the code you specified won't work even if you fix the stack overflow. Since you're trying to insert()
docs that are already in the database, all the inserts will fail because of _id
conflicts. You'd really be much better off just using a stream() to read the results one at a time and then save()
them back into the db.
I was having this same issue and I started digging through the mongoose source code (version 3.8.14). Eventually it led me to this line within
- mongoose/node_modules/mongodb/lib/mongodb/collection/core.js -> insert(...) -> insertWithWriteCommands(...) ->
mongoose/node_modules/mongodb/lib/mongodb/collection/batch/ordered.js -> bulk.insert(docs[i]) -> addToOperationsList(...) -> bson.calculateObjectSize(document, false);
var bsonSize = bson.calculateObjectSize(document, false);
Apparently, this calls BSON.calculateObjectSize, which calls calculateObjectSize which then infinitely recurses. I wasn't able to dig that far in to what caused it, but figured that it may have something to do with the mongoose wrapper binding functions to the Schema. Since I was inserting raw data into mongoDB, once I decided to change the bulk insert in mongoose to a standard javascript object, the problem went away and bulk inserts happened correctly. You might be able to do something similar.
Essentially, my code went from
//EDIT: mongoose.model needs lowercase 'm' for getter method
var myModel = mongoose.model('MyCollection');
var toInsert = myModel();
var array = [toInsert];
myModel.collection.insert(array, {}, function(err, docs) {});
to
//EDIT: mongoose.model needs lowercase 'm' for getter method
var myModel = mongoose.model('MyCollection');
var toInsert = { //stuff in here
name: 'john',
date: new Date()
};
var array = [toInsert];
myModel.collection.insert(array, {}, function(err, docs) {});