javascript - pilas - que es una pila en java
Mangosta-RangeError: se ha excedido el tamaño máximo de la pila de llamadas (6)
Confirmado, pero no es un error. Model.collection.insert()
puentea a Mongoose y le dice al controlador del nodo que inserte un objeto que contenga partes internas de mangosta como $__
, etc. El desbordamiento de pila probablemente se deba a que bson está tratando de calcular el tamaño de un objeto que hace referencia indirectamente.
Para abreviar, use Document.toObject()
, para eso sirve: 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();
}
});
Además, el código que especificó no funcionará aunque arregle el desbordamiento de la pila. Como intenta insert()
documentos que ya están en la base de datos, todos los insertos fallarán debido a conflictos de _id
. Sería mucho mejor que simplemente usar una secuencia () para leer los resultados de uno en uno y luego save()
en el archivo db.
Estoy tratando de insertar documentos a granel en MongoDB (evitando Mongoose y usando el controlador nativo, ya que Mongoose no admite la inserción masiva de una matriz de documentos). La razón por la que estoy haciendo esto es para mejorar la velocidad de escritura.
Recibo el error "RangeError: Maximum Call Stack Size Exceeded" en console.log (err) en el siguiente código:
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();
}
});
}
Muy similar a: https://stackoverflow.com/questions/24356859/mongoose-maximum-call-stack-size-exceeded
Quizás es algo sobre el formato de la matriz de respuestas que devuelve Mongoose que significa que no puedo insertar directamente usando MongoDB de forma nativa. Intenté .toJSON () en cada respuesta pero no tuve suerte.
Todavía obtengo el error incluso con una cantidad muy pequeña de datos, pero recorrer y llamar al guardado de Mangosta en cada documento individualmente funciona bien.
EDITAR: Creo que está relacionado con este problema: http://howtosjava.blogspot.com.au/2012/05/nodejs-mongoose-rangeerror-maximum-call.html
Mi esquema de respuestas es:
var ResponseSchema = new Schema({
user: {
type: Schema.ObjectId,
ref: ''User''
},
randomUUID: String,
status: String,
submitted: Date,
initialEmailId: String,
survey: String,
answers: [AnswerSchema]
});
Entonces, las respuestas son un subdocumento dentro de las respuestas. No estoy seguro de cómo solucionarlo ...
Estaba teniendo el mismo problema y comencé a buscar el código fuente de mangostas (versión 3.8.14). Eventualmente me llevó a esta línea dentro
- 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);
Aparentemente, esto llama a BSON.calculateObjectSize, que llama a calculateObjectSize que luego recursivamente. No pude profundizar tanto en lo que lo causó, pero pensé que podría tener algo que ver con las funciones de enlace de la envoltura de mangosta para el Esquema. Como estaba insertando datos sin procesar en mongoDB, una vez que decidí cambiar la inserción masiva en mangosta a un objeto javascript estándar, el problema desapareció y las inserciones en bloque se realizaron correctamente. Es posible que puedas hacer algo similar.
Esencialmente, mi código pasó de
//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) {});
a
//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) {});
Esto también ocurre si hay una duplicación del valor _id
. La mayoría de las situaciones serán cuando podría crear un nuevo registro a partir de un registro existente.
Eliminando el _id
e insertando el registro y dejando que Mongoose / MongoDb se encargue de la creación del id.
He enfrentado un problema similar.
//manyvalues is array of objects
schema.methods.somemethod = function(manyvalues,callback) {
this.model(collection).collection.insertMany(manyvalues,callback);
}
Pero esto causó el error [RangeError: se excedió el tamaño máximo de la pila de llamadas] . Así que he creado un nuevo modelo a partir de muchos valores y lo usé a continuación y funcionó.
schema.methods.somemethod = function(manyvalues,callback){
var list = JSON.parse(JSON.stringify(manyvalues));//created a new object.
this.model(collection).collection.insertMany(list,callback);
}
El problema puede ser causado si muchos valores se cambian internamente.
Tuve un problema similar, fue que estaba consultando un campo que no existía en el esquema usando $ ne (otros operadores de consulta pueden tener un problema similar)
var TestSchema = new Schema({
test:[]
});
...
models.Test.findOne({"test2": {$ne: "t"} })...
En el ejemplo anterior estoy probando para test2 en lugar de prueba
chicos! Me he enfrentado a ese extraño error hoy. Sucedió porque tenía un esquema con propiedades de ref
y traté de pasar en create
/ update
todo el documento relacionado. Cambié el argumento a _id
solo y eso funcionó. Funciona de maravilla. Encontré la respuesta here (baje hasta February 21, 2013, 8:05 pm gustavohenke
comentario de February 21, 2013, 8:05 pm gustavohenke
).