Mongoose – RangeError:最大调用堆栈大小超出
我试图批量插入文件到MongoDB(所以绕过Mongoose和使用本地驱动程序,而不是Mongoose不支持批量插入文档数组)。 我这样做的原因是为了提高写作速度。
我在下面的代码中的console.log(err)处收到错误“RangeError:Maximum Call Stack Size Exceeded”
function _fillResponses(globalSurvey, optionsToSelectRegular, optionsToSelectPiped, responseIds, callback) { Response.find({'_id': {$in: responseIds}}).exec(function(err, responses) { if (err) { return callback(err); } if (globalSurvey.questions.length) { responses.forEach(function(response) { console.log("Filling response: " + response._id); response.answers = []; globalAnswers = {}; globalSurvey.questions.forEach(function(question) { ans = _getAnswer(question, optionsToSelectRegular, optionsToSelectPiped, response); globalAnswers[question._id] = ans; response.answers.push(ans); }); }); Response.collection.insert(responses, function(err, responsesResult) { console.log(err); callback() }); } else { callback(); } }); }
所以类似于: https : //stackoverflow.com/questions/24356859/mongoose-maximum-call-stack-size-exceeded
也许这是关于Mongoose返回的响应数组格式的问题,这意味着我不能直接使用MongoDB本地插入? 我已经尝试.toJSON()在每个响应,但没有运气。
即使只有非常less量的数据,我仍然得到错误,但循环,并调用每个文件上的Mongoose保存单独工作正常。
编辑:我认为这是有关这个问题: http : //howtosjava.blogspot.com.au/2012/05/nodejs-mongoose-rangeerror-maximum-call.html
我的答案是:
var ResponseSchema = new Schema({ user: { type: Schema.ObjectId, ref: 'User' }, randomUUID: String, status: String, submitted: Date, initialEmailId: String, survey: String, answers: [AnswerSchema] });
所以答案是答案中的一个子文件。 不知道如何解决它,虽然….
我有这个相同的问题,我开始挖掘mongoose的源代码(版本3.8.14)。 最终它把我引向了这条线
- 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);
显然,这个调用BSON.calculateObjectSize,它调用calculateObjectSize然后无限地recursion。 我无法深入了解导致它的原因,但认为这可能与模式的mongoose封装绑定function有关。 自从我将原始数据插入到mongoDB中后,一旦我决定将mongoose中的批量插入更改为标准的javascript对象,问题就消失了,并且批量插入正确发生。 你也许可以做类似的事情。
本质上,我的代码从
//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) {});
至
//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) {});
确认,但不是一个错误。 Model.collection.insert()
绕过了Mongoose,所以你告诉节点驱动程序插入一个包含mongoose内部Model.collection.insert()
如$__
等)的对象。堆栈溢出可能是因为bson试图计算引用的对象的大小本身间接。
长话短说,使用Document.toObject()
,这就是它的作用: 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(); } });
而且,即使修复堆栈溢出,您指定的代码也不起作用。 由于您试图insert()
已经存在于数据库中的insert()
文档,因为_id
冲突,所有插入都会失败。 如果使用stream()来一次读取一个结果,然后save()
它们save()
到db中,你真的会好得多。
伙计们! 我今天遇到了这个奇怪的错误。 这是因为我有一个与ref
属性的架构,并试图通过create
/ update
整个相关文件。 我只改变了_id
参数,而且这个技巧。 奇迹般有效。 我在这里find了答案(滚动到February 21, 2013, 8:05 pm gustavohenke
评论)。
我遇到了类似的问题。
//manyvalues is array of objects schema.methods.somemethod = function(manyvalues,callback) { this.model(collection).collection.insertMany(manyvalues,callback); }
但是这会导致错误[RangeError:超出最大调用堆栈大小] 。 所以我创造了许多值的新模型,并用它作为下面的工作。
schema.methods.somemethod = function(manyvalues,callback){ var list = JSON.parse(JSON.stringify(manyvalues));//created a new object. this.model(collection).collection.insertMany(list,callback); }
如果内部更改许多值,则可能会导致问题。
如果有_id
值的重复,也会发生这种情况。 大多数情况下,您可能会从现有logging创build新logging。
删除_id
并插入logging,并让Mongoose / MongoDb负责创buildid。
我有一个类似的问题,那就是我正在使用$ ne查询模式中不存在的字段(其他查询操作符可能有类似的问题)
var TestSchema = new Schema({ test:[] }); ... models.Test.findOne({"test2": {$ne: "t"} })...
在上面的例子中,我正在testingtest2而不是testing