Mongooseクエリから返されたデータを変更できないのはなぜですか(例:findById)


94

Mongooseクエリから返されたデータの一部を変更しようとしても、何の効果もありません。

私はこれを昨日約2時間、あらゆる種類の_.clone()sを使用して、一時的なストレージ変数などを使用して理解しようとしました。最後に、私が夢中になっていたときに、解決策を見つけました。そのため、将来的には誰か(fuuuture!)に保存の問題が発生する可能性があると考えました。

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


回答:


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はもう一度感謝を言いたかっただけです。1年半後、クライアントが何かをデバッグするのを助けていました。彼は週末に何かを理解するために費やしましたが、それは彼がマングースオブジェクトを変更しようとしていたためであることが
わかりました

1
2年後、まだそれを押しつぶします。lean()が存在することすら知らなかった。
Petrogad

1
@Fizzixはaggregate常に結果をプレーンオブジェクトとして提供するため、は必要ありませんlean()
JohnnyHK

1
3年後、それを理解するために費やし、1時間を費やしました。私の一日を救った!ありがとう
Noy

2
ありがとうございました!これは本当に役に立ちましたが、なぜオブジェクトを変更できないのですか?それはどんな特別な目的ですか?
Robert Fedus

46

Mongooseのドキュメントではこれが十分に明確にされていないと思いますが、クエリで返されるデータ(res.send()を使用することはできますが)は実際にはMongoose Documentオブジェクトであり、JSONオブジェクトではありません。しかし、これを1行で修正できます...

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 2015年

1
これにより、開発者が付けた仮想も削除されますか?
mjwrazor 2016

5
TypeError: data.toObject is not a function私は、この、同じだtoJSON
Luzan BARAL

を変更する代わりにresult、私は変更することができましたresult._doc
n番目の-チリ

@Luzan Baralそれは、Arrayオブジェクトに対してこれらの関数を使用しているためです。JSON.parse(JSON.stringify(data))オブジェクトの配列に代わりに使用
mohit
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.