web-dev-qa-db-ja.com

MongoDBを使用してネストされた配列を更新する

ネストされた配列の値を更新しようとしていますが、機能しません。

私のオブジェクトはこんな感じ

 {
    "_id": {
        "$oid": "1"
    },
    "array1": [
        {
            "_id": "12",
            "array2": [
                  {
                      "_id": "123",
                      "answeredBy": [],
                  },
                  {
                      "_id": "124",
                      "answeredBy": [],
                  }
             ],
         }
     ]
 }

「answeredBy」配列に値をプッシュする必要があります。

以下の例では、「123 _id」オブジェクトの「answeredBy」配列に「success」文字列をプッシュしようとしましたが、機能しません。

callback = function(err,value){
     if(err){
         res.send(err);
     }else{
         res.send(value);
     }
};
conditions = {
    "_id": 1,
    "array1._id": 12,
    "array2._id": 123
  };
updates = {
   $Push: {
     "array2.$.answeredBy": "success"
   }
};
options = {
  upsert: true
};
Model.update(conditions, updates, options, callback);

私はこれを見つけました link 、しかし、その答えは、配列の代わりに構造のようなオブジェクトを使用するべきだとだけ言っています。これは私の状況では適用できません。本当にオブジェクトを配列にネストする必要があります

ここで私を助けていただければ幸いです。これを理解するために何時間も費やしてきました。

前もって感謝します!

28
masanorinyo

これは非常に古い質問であることは知っていますが、自分でこの問題に苦労し、自分が信じていること、より良い答えを見つけました。

この問題を解決する方法は、 _Sub-Documents_ を使用することです。これは、スキーマ内にスキーマをネストすることにより行われます

_MainSchema = new mongoose.Schema({
   array1: [Array1Schema]
})

Array1Schema = new mongoose.Schema({
   array2: [Array2Schema]
})

Array2Schema = new mongoose.Schema({
   answeredBy": [...]
})
_

これにより、オブジェクトは表示されているように見えますが、各配列にはサブドキュメントが表示されます。これにより、目的のサブドキュメントにドットを挿入できます。 _.update_を使用する代わりに、_.find_または_.findOne_を使用して、更新するドキュメントを取得します。

_Main.findOne((
    {
        _id: 1
    }
)
.exec(
    function(err, result){
        result.array1.id(12).array2.id(123).answeredBy.Push('success')
        result.save(function(err){
            console.log(result)
        });
    }
)
_

_.Push(_)関数を自分でこのように使用したことがないため、構文が正しくない可能性がありますが、.set().remove()の両方を使用しました。 。

6
Jesper Nielsen