Warum können Sie die von einer Mungo-Abfrage zurückgegebenen Daten nicht ändern (z. B. findById)?

94

Wenn ich versuche, einen Teil der von einer Mungo-Abfrage zurückgegebenen Daten zu ändern, hat dies keine Auswirkungen.

Ich habe gestern ungefähr 2 Stunden lang versucht, dies herauszufinden, mit allen Arten von _.clone()s, unter Verwendung temporärer Speichervariablen usw. Schließlich fand ich eine Lösung, als ich verrückt wurde. Also dachte ich mir, dass jemand in der Zukunft (fyuuuture!) Das Problem mit dem Speichern haben könnte.

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
quelle
Mögliches Duplikat von stackoverflow.com/q/9952649/4748042
martinho

Antworten:

160

In solchen Fällen, in denen Sie ein einfaches JS-Objekt anstelle einer vollständigen Modellinstanz möchten, können Sie lean()die Abfragekette folgendermaßen aufrufen :

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

Dieser Weg dataist bereits ein einfaches JS-Objekt, das Sie nach Bedarf bearbeiten können.

JohnnyHK
quelle
8
Btw @JohnnyHK wollte sich nur noch einmal bedanken. Eineinhalb Jahre später half er einem Kunden, etwas zu debuggen. Er verbrachte ein Wochenende damit, etwas herauszufinden, es stellte sich heraus, dass er versuchte, das Mungobjekt zu modifizieren; P
Toli
1
2 Jahre später und immer noch zerquetschen. Ich wusste nicht einmal, dass Lean () da war.
Petrogad
1
@Fizzix aggregateliefert seine Ergebnisse immer als einfache Objekte, sodass dies nicht erforderlich ist lean().
JohnnyHK
1
3 Jahre später und verbrachte eine ganze Stunde damit, es herauszufinden. Hat meinen ganzen Tag gerettet! Danke
Noy
2
Danke dir! Das hat wirklich geholfen, aber warum ist es unmöglich, das Objekt zu ändern? Was ist das für ein besonderes Objekt?
Robert Fedus
46

Ich denke, die Mongoose-Dokumentation macht dies nicht klar genug, aber die in der Abfrage zurückgegebenen Daten (obwohl Sie sie res.send () können) sind tatsächlich ein Mongoose-Dokumentobjekt und KEIN JSON-Objekt. Aber Sie können dies mit einer Zeile beheben ...

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
quelle
12
Sie können auch verwenden toObject(), was dasselbe tut, toJSON()aber mit einem weniger verwirrenden Namen.
JohnnyHK
1
Wird dies auch die vom Entwickler angelegten Virtuals beseitigen?
mjwrazor
5
TypeError: data.toObject is not a functionIch habe das gleiche, mittoJSON
Luzan Baral
Anstatt das resultzu ändern, konnte ich es ändern result._doc.
n-chile
@Luzan Baral Das liegt daran, dass Sie diese Funktion für das Array-Objekt verwenden. Verwenden Sie JSON.parse(JSON.stringify(data))stattdessen für Arrays von Objekten
Mohit