programing

Mongoose - RangeError: 최대 콜 스택 크기 초과

css3 2023. 6. 19. 21:57

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()을 시도했지만 실패했습니다.

아주 적은 양의 데이터에도 오류가 발생하지만 루프를 통해 각 문서에 있는 Mongoose save를 개별적으로 호출하면 문제가 없습니다.

편집: 이 문제와 관련이 있다고 생각합니다. 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]
}); 

즉, 응답은 응답 내의 하위 문서입니다.어떻게 고치는지는 잘 모르겠지만….

저는 같은 문제를 겪고 있었고 몽구스 소스 코드(버전 3.8.14)를 조사하기 시작했습니다.결국 그것은 나를 이 선 안으로 이끌었습니다.

  • mongoose/node_modules/mongodb/lib/mongodb/collection.js -> insert(...) -> InsertWithWriteCommands(...) ->
  • mongoose/node_modules/mongodb/lib/mongodb/collection/batch/ordered.js -> bulk.insert(docs[i]) -> 추가ToOperationsList(...) -> bson.calculateObjectSize(문서, false);

    varbsonSize = bson.calculateObjectSize(문서, 거짓);

분명히, 이것은 BSON.calculateObjectSize를 호출하고, 이것은 calculateObjectSize를 호출한 다음 무한 반복합니다.저는 그것의 원인을 그렇게까지 파헤칠 수는 없었지만, 그것이 스키마에 대한 몽구스 래퍼 바인딩 기능과 관련이 있을 것이라고 생각했습니다.mongoDB에 raw data를 삽입할 때 mongoose의 bulk insert를 표준 javascript object로 변경하기로 한 후 문제가 해결되어 bulk insert가 올바르게 발생하였습니다.당신은 비슷한 것을 할 수 있을지도 모릅니다.

기본적으로, 내 코드는

//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와 같은 개체가 를 삽입하도록 입니다.$__스택 오버플로는 아마도 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();
    }
});

또한 스택 오버플로를 수정해도 지정한 코드가 작동하지 않습니다.당이노는이상하력신▁to이▁you상▁sincere▁trying'.insert()은 " " " ", ", " 할 것입니다._id갈등들.스트림()을 사용하여 결과를 한 번에 하나씩 읽는 것이 훨씬 나을 것입니다.save()그들은 다시 DB로 돌아갑니다.

여러분! 저는 오늘 그 이상한 오류에 직면했습니다.그것은 내가 스키마를 가지고 있었기 때문에 발생했습니다.ref하여 부동산과시습니다했도전달을▁in다▁proper▁pass.create/update관련 문서 전체나는 주장을 로 바꿨습니다._id오직 그것만이 요령을 부렸습니다.매력적으로 작동합니다.여기서 을 찾았습니다(아래로 스크롤하여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 기존의 record에서 새 수 있습니다. 대부분의 경우 기존 레코드에서 새 레코드를 만들 수 있습니다.

_id레코드를 삽입하고 Mongoose/MongoDb가 ID 생성을 처리하도록 합니다.

저도 같은 문제가 있었습니다. 버전은 스구버전입니다.5.13.14내 스택 추적은 다음과 같습니다.

RangeError: Maximum call stack size exceeded
    at minimize (...\node_modules\mongoose\lib\document.js:3564:18)
    at minimize (...\node_modules\mongoose\lib\document.js:3576:18)
    at minimize (...\node_modules\mongoose\lib\document.js:3576:18)
    at minimize (...\node_modules\mongoose\lib\document.js:3576:18)
    at minimize (...\node_modules\mongoose\lib\document.js:3576:18)
    at minimize (...\node_modules\mongoose\lib\document.js:3576:18)
    at minimize (...\node_modules\mongoose\lib\document.js:3576:18)

문제를 해결하는 두 가지 방법을 찾았습니다.

  1. 용사를 합니다.toObject()방법:
const model = await MyModel.findOne(conditions);
return model?.toObject();
  1. 용사를 합니다.minimize: falsetoJSON스키마의 옵션:
export const MySchema = new Schema({
    ...
}, {
    ...
    toJSON: {
        getters: true,
        // !!! HERE !!!
        minimize: false,
    },
    ...
});

반응 객체에서 순환 참조를 확인합니다.순환 참조로 인해 비슷한 문제에 직면했습니다.

비슷한 문제가 있었습니다. $ne을 사용하여 스키마에 존재하지 않는 필드를 쿼리하는 중이었습니다(다른 쿼리 연산자도 비슷한 문제가 있을 수 있음).

var TestSchema = new Schema({
  test:[]
});
...
models.Test.findOne({"test2": {$ne: "t"} })...

위의 예에서 나는 테스트 대신 test2를 테스트하고 있습니다.

언급URL : https://stackoverflow.com/questions/24466366/mongoose-rangeerror-maximum-call-stack-size-exceeded