Perché non puoi modificare i dati restituiti da una query Mongoose (es: findById)


94

Quando provo a modificare qualsiasi parte dei dati restituiti da una query Mongoose, non ha alcun effetto.

Ho cercato di capirlo per circa 2 ore ieri, con tutti i tipi di messaggi _.clone(), utilizzando variabili di archiviazione temporanea, ecc. Infine, proprio quando pensavo di impazzire, ho trovato una soluzione. Quindi ho pensato che qualcuno in futuro (fyuuture!) Potrebbe avere il problema del salvataggio.

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


Risposte:


160

Per casi come questo in cui desideri un semplice oggetto JS invece di un'istanza di modello completa, puoi chiamare lean()la catena di query in questo modo:

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

In questo modo dataè già un semplice oggetto JS che puoi manipolare secondo le tue necessità.


8
Btw @JohnnyHK volevo solo dire grazie ancora. Un anno e mezzo dopo stava aiutando un cliente a eseguire il debug di qualcosa. Ha trascorso un fine settimana cercando di capire qualcosa, si è scoperto che era perché stava cercando di modificare l'oggetto Mongoose; P
Toli

1
2 anni dopo e ancora schiacciandolo. Non avevo nemmeno realizzato che lean () fosse lì.
Petrogad

1
@Fizzix aggregatefornisce sempre i suoi risultati come oggetti semplici, quindi non ce n'è bisogno lean().
JohnnyHK

1
3 anni dopo e ho passato un'intera ora a cercare di capirlo. Mi ha salvato l'intera giornata! Grazie
Noy

2
Grazie! Questo ha davvero aiutato, ma perché è impossibile modificare l'oggetto? Che tipo di oggetto speciale è?
Robert Fedus

46

Penso che la documentazione di Mongoose non lo renda abbastanza chiaro, ma i dati restituiti nella query (anche se puoi res.send () it) è in realtà un oggetto Mongoose Document e NON un oggetto JSON. Ma puoi risolvere questo problema con una riga ...

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
Puoi anche usare toObject(), che fa la stessa cosa toJSON()ma con un nome meno confuso.
JohnnyHK

1
Questo eliminerà anche i virtual messi in atto dallo sviluppatore?
mjwrazor

5
TypeError: data.toObject is not a functionHo toJSON
capito

Invece di modificare il result, sono stato in grado di modificare result._doc.
nth-chile

@Luzan Baral Questo è perché stai usando queste funzioni per l'oggetto Array. Utilizzare JSON.parse(JSON.stringify(data))invece per array di oggetti
mohit
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.