Mengapa Anda tidak bisa mengubah data yang dikembalikan oleh Mongoose Query (contoh: findById)

95

Ketika saya mencoba untuk mengubah bagian mana pun dari data yang dikembalikan oleh Mongoose Query itu tidak berpengaruh.

Saya mencoba memikirkan hal ini selama sekitar 2 jam kemarin, dengan semua jenis _.clone(), menggunakan variabel penyimpanan sementara, dll. Akhirnya, ketika saya merasa gila, saya menemukan solusi. Jadi saya pikir seseorang di masa depan (fyuuuture!) Mungkin memiliki masalah penyimpanan.

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);
            }
        });
    });
});
Toli
sumber
kemungkinan duplikat stackoverflow.com/q/9952649/4748042
martinho

Jawaban:

161

Untuk kasus seperti ini di mana Anda menginginkan objek JS biasa daripada contoh model lengkap, Anda dapat memanggil lean()rantai kueri seperti ini:

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);
            }
        });
    });
});

Cara dataini sudah menjadi objek JS biasa yang dapat Anda manipulasi sesuai kebutuhan.

JohnnyHK
sumber
8
Btw @JohnnyHK hanya ingin mengucapkan terima kasih lagi. Satu setengah tahun kemudian membantu klien men-debug sesuatu. Dia menghabiskan akhir pekan mencoba mencari sesuatu, ternyata itu karena dia mencoba untuk memodifikasi Objek Luwak; P
Toli
1
2 tahun kemudian dan masih menghancurkannya. Bahkan tidak menyadari lean () ada di sana.
Petrogad
1
@Fizzix aggregateselalu memberikan hasil sebagai objek biasa, jadi tidak perlu lean().
JohnnyHK
1
3 tahun kemudian dan menghabiskan dan seluruh jam mencoba mencari tahu. Menyelamatkan seluruh hari saya! Terima kasih
Noy
2
Terima kasih! Ini benar-benar membantu, tetapi mengapa tidak mungkin untuk memodifikasi objek? Benda khusus macam apa itu?
Robert Fedus
46

Saya pikir dokumentasi Mongoose tidak membuat ini cukup jelas, tetapi data yang dikembalikan dalam kueri (meskipun Anda dapat res.send () itu) sebenarnya adalah objek Dokumen Mongoose, dan BUKAN objek JSON. Tetapi Anda dapat memperbaikinya dengan satu baris ...

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);
            }
        });
    });
});
Toli
sumber
12
Anda juga dapat menggunakan toObject(), yang melakukan hal yang sama toJSON()tetapi dengan nama yang tidak terlalu membingungkan.
JohnnyHK
1
Apakah ini juga akan menghilangkan virtual yang dipasang oleh pengembang juga?
mjwrazor
5
TypeError: data.toObject is not a functionSaya mendapatkan ini, sama dengantoJSON
Luzan Baral
Alih-alih memodifikasi file result , saya bisa memodifikasi result._doc.
nth-chile
@Luzan Baral Itu karena Anda menggunakan fungsi ini untuk objek Array. Gunakan JSON.parse(JSON.stringify(data))sebagai gantinya untuk Array objek
mohit