2016-07-08 10 views
2

私はこのようなオブジェクトを持っています。Node.js - Mongoose - req.bodyのすべての値を含むネストされた配列を更新します。

{ 
    _id: '577fe7a842c9b447', 
    name: 'Jacob\'s Bronze Badges', 
    competitors: [ 
    { 
     _id: '577fe7a842c9bd6d', 
     name: 'Peter\'s Silver Badges', 
     sites: [ 
     { 
      _id: '577fe7a842c9bd6d', 
      name: 'Facebook', 
      url: 'fb.com/peter' 
     }, 
     { 
      _id: '577fe7a842c9bd6d' 
      name: 'Google', 
      url: 'google.com/peter' 
     } 
     ] 
    }, 
    { 
     _id: '599fe7a842c9bd6d', 
     name: 'Paul\'s Gold Badges', 
     sites: [ 
     { 
      '_id': '577fe7a842c9bd6d', 
      name: 'Facebook', 
      url: 'fb.com/paul' 
     }, 
     { 
      _id: '577fe7a842c9bd6d', 
      name: 'Google', 
      url: 'google.com/paul' 
     } 
     ] 
    } 
    ] 
} 

私の目標は、req.bodyからすべての値を持つ内部でcompetitorsアレイとアップデートの項目を参照することです。私はこのコードをthisの回答に基づいて、またthis other oneに基づいています。

Location.update(
    { 'competitors._id': req.params.competitorId, }, 
    { $set: { 'competitors.$': req.body, }, }, 
    (err, result) => { 
    if (err) { 
     res.status(500) 
     .json({ error: 'Unable to update competitor.', }); 
    } else { 
     res.status(200) 
     .json(result); 
    } 
    } 
); 

私はピーターのシルバーバッジを更新するためにlocalhost:3000/competitors/577fe7a842c9bd6dに私のHTTP PUTを送ります。リクエストボディは、次のとおりです。

{ 
    "name": "McDonald's" 
} 

問題は、私は_id: req.params.competitorIdでライバルを設定するために$setを使用する場合、私はreq.bodyにあるかわからないということです。私は、配列内のオブジェクトを更新するために全体req.bodyを使用したいが、私が行うとき、そのオブジェクトが上書きされ、その代わりに新しい名前を得るための、ピーターのシルバーバッジは次のようになります。

{ 
    name: 'McDonald\'s', 
    sites: [] 
} 

どのように更新することができます配列内のオブジェクトは、オブジェクトの_idがすべてのフィールドがreq.bodyで、保持したいフィールドを削除せずに知っていますか?

オブジェクトが再初期化されたため、sites配列が空であると思います。私のスキーマでは、それを初期化するためにsites: [sitesSchema]があります。だから私は、competitors[_id]オブジェクト全体が新しい名前で上書きされていると仮定していて、次にmyschemaからsites: [sitesSchema]を取得すると仮定しています。

答えて

6

$setには、$位置演算子を使用する必要があります。 req.bodyの内容に基づいてこれらのプロパティを動的に割り当てるには、プログラムで$setを構築する必要があります。

あなたが名前を更新する場合は、次の操作を行います:あなたがプログラム的にreq.bodyを使用して$setを構築する可能性がある

Location.update(
    { 'competitors._id': req.params.competitorId }, 
    { $set: { 'competitors.$.name': req.body.name }}, 
    (err, result) => { 
    if (err) { 
     res.status(500) 
     .json({ error: 'Unable to update competitor.', }); 
    } else { 
     res.status(200) 
     .json(result); 
    } 
} 
); 

一つの方法は、以下の手順を実行している:

let updateObj = {$set: {}}; 
for(var param in req.body) { 
    updateObj.$set['competitors.$.'+param] = req.body[param]; 
} 

を参照してくださいthis詳細については、答えをご覧ください。

0

埋め込みドキュメントを$ operatorで更新するには、ほとんどの場合、$演算子にドット表記を使用する必要があります。

Location.update(
    { _id: '577fe7a842c9b447', 'competitors._id': req.params.competitorId, }, 
    { $set: { 'competitors.$.name': req.body.name, }, }, 
    (err, result) => { 
    if (err) { 
     res.status(500) 
     .json({ error: 'Unable to update competitor.', }); 
    } else { 
     res.status(200) 
     .json(result); 
    } 
    } 
); 
関連する問題