Чому ви не можете змінити дані, повернені запитом Mongoose (наприклад: findById)


94

Коли я намагаюся змінити будь-яку частину даних, що повертаються запитом Mongoose, це не впливає.

Я намагався це зрозуміти приблизно 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);
            }
        });
    });
});


можливо дублікат stackoverflow.com/q/9952649/4748042
Martinho

Відповіді:


160

У таких випадках, коли вам потрібен звичайний об'єкт 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, яким можна маніпулювати, як потрібно.


8
До речі, @JohnnyHK просто хотів ще раз подякувати. Через півтора року допомагав клієнту щось налагоджувати. Він провів вихідні, намагаючись щось зрозуміти, виявляється, це тому, що він намагався модифікувати Об'єкт Мангуст; P
Толі

1
Через 2 роки і досі це розчавлює. Навіть не підозрював, що там є lean ().
Петрогад,

1
@Fizzix aggregateзавжди надає свої результати як звичайні об'єкти, тому немає необхідності lean().
JohnnyHK

1
Через 3 роки і цілу годину намагався це зрозуміти. Врятував мій цілий день! Дякую
Ной

2
Дякую! Це справді допомогло, але чому неможливо змінити об’єкт? Що це за особливий об'єкт?
Роберт Федус,

46

Я думаю, що документація Mongoose недостатньо чітко це робить, але дані, що повертаються у запиті (хоча ви можете res.send () це), насправді є об'єктом документа Mongoose, а НЕ об'єктом 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);
            }
        });
    });
});

12
Ви також можете використовувати toObject(), що робить те саме, що і toJSON()з менш заплутаною назвою.
JohnnyHK

1
Чи буде це також позбутися віртуальних програм, які розробник також одягне?
mjwrazor

5
TypeError: data.toObject is not a functionЯ отримав це, те саме зtoJSON
Лузан Барал

Замість модифікації result, я зміг змінити result._doc.
nth-chile

@Luzan Baral Це тому, що ви використовуєте ці функції для об'єкта Array. Використовуйте JSON.parse(JSON.stringify(data))замість цього для масивів об’єкта
mohit
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.