为什么不能修改 Mongoose 查询(如 findById)返回的数据

当我试图更改由 Mongoose 查询返回的数据的任何部分时,都没有效果。

我昨天花了2个小时试图弄明白这个问题,使用了各种 _.clone(),使用了临时存储变量等等。最后,就在我以为自己要疯了的时候,我找到了一个解决办法。所以我想未来会有人(未来!)可能有存档问题。

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);
}
});
});
});
34257 次浏览

I think the Mongoose documentation doesn't make this clear enough, but the data returned in the query (although you can res.send() it) is actually a Mongoose Document object, and NOT a JSON object. But you can fix this with one line...

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

For cases like this where you want a plain JS object instead of a full model instance, you can call lean() on the query chain like so:

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

This way data is already a plain JS object you can manipulate as you need to.

I was using mongoose and here are the workaround I did to resolve it:

Mongoose returns MongooseDocument objects and not plain JSON objects. So use the lean() method on object which will convert it into JSON, and from there you can change it

const leanDoc = await MyModel.findOne().lean();

---------------------------------OR---------------------------------

2): Create a deep copy of the result returned by find query as shown below

Books.find({}).then(books => {
books = JSON.parse(JSON.stringify(books));
//now you can update the books object
}