Почему вы не можете изменять данные, возвращаемые Mongoose Query (например: findById)

Когда я пытаюсь изменить любую часть данных, возвращаемых Mongoose Query, это не влияет.

Я пытался выяснить это примерно 2 часа вчера со всеми типами _.clone() s, используя временные переменные хранилища и т.д. Наконец, когда я, хотя я сошел с ума, нашел решение. Поэтому я решил, что кто-то в будущем (fyuuuture!) Может иметь проблему с сохранением.

Survey.findById(req.params.id, function(err, data){
    var len = data.survey_questions.length;
    var counter = 0;

    _.each(data.survey_questions, function(sq){
        Question.findById(sq.question, function(err, q){
            sq.question = q; //has no effect

            if(++counter == len) {
                res.send(data);
            }
        });
    });
});

Ответ 1

В таких случаях, когда вам нужен простой объект JS вместо полного экземпляра модели, вы можете вызвать lean() в цепочке запросов так:

Survey.findById(req.params.id).lean().exec(function(err, data){
    var len = data.survey_questions.length;
    var counter = 0;

    _.each(data.survey_questions, function(sq){
        Question.findById(sq.question, function(err, q){
            sq.question = q;

            if(++counter == len) {
                res.send(data);
            }
        });
    });
});

Этот способ data уже является простым JS-объектом, с которым вы можете манипулировать, как вам нужно.

Ответ 2

Я думаю, что документация Mongoose не делает этого достаточно ясным, но данные, возвращаемые в запросе (хотя вы можете res.send() это) на самом деле объект Mongoose Document, а НЕ объект JSON. Но вы можете исправить это одной строкой...

Survey.findById(req.params.id, function(err, data){
    var len = data.survey_questions.length;
    var counter = 0;

    var data = data.toJSON(); //turns it into JSON YAY!

    _.each(data.survey_questions, function(sq){
        Question.findById(sq.question, function(err, q){
            sq.question = q;

            if(++counter == len) {
                res.send(data);
            }
        });
    });
});