2017-03-19 8 views
1

まず、この問題を部分的に解決するthis stack overflow entryを読みましたが、複数のエントリを動的に追加する必要があります。複数の値でネストされたオブジェクトを部分的に更新するExpress.js MongoDB

エクスプレスとmongodbドライバを使用して投票するウェブサイトがあり、投稿後に投票に追加オプションを追加できるようにします(追加アイテムの追加のみ可能、既存アイテムの編集はできません)。 )。

すべてのオプション(可能な回答)は、answerの後に数字(最大5)と表示されます。

だから我々が持っているデータベースに:

{ 
    "_id": { 
     "$oid": "58cdf0023cefa56136afb50f" 
    }, 
    "question": "Who is the best Bob?", 
    "options": { 
     "answer1": { 
      "option": "Bob Dylan", 
      "votes": 2 
     }, 
     "answer2": { 
      "option": "Bob Geldof", 
      "votes": 0 
     } 
    } 
} 

だから、このエントリでは、ユーザーは三つの追加解答オプションを追加することができます。

追加の回答名(このdbの例ではanswer3など)をハードコードすると、入れ子になったoptionsプロパティを更新できます。

var toInsert = { options: 
    { answer3: { option: 'Bob Saget', votes: 0 }, 
    answer4: { option: 'Bob Marley', votes: 0 } } } 

    db.collection('questions') 
    .findOneAndUpdate({"_id": questionId}, {$set : {'options.answer3': [toInsert.answer3]}}, {upsert: true}, (err, result) => { 
    if (err) return res.send(err) 
    res.send("worked"); 
    }) 

EDIT:適切な答えを私はちょうど彼もそれにバグがあり実現してきたので、私もハードコードすることはできません。しかし、ここではわかりやすくするためにこれを残しておきます。

しかし、入れ子になったoptionsオブジェクトを、ユーザーが望むものに応じて1-3の新しいオプションで動的に更新し、既存のデータだけをoptionsオブジェクトに残しておく必要があります。上の例のコードでは、answer3answer4の両方をtoInsertから挿入したいと考えています。

私はノードとMongoDBをとても使い慣れていて、「ねえ、私はfor loopに入れることができます」という私の考えは、それを働かせても悪い考えです。

答えて

1

回答文書をオプションの埋め込み配列文書に置き換えることで、後の作業を達成できます。

{ 
    "_id": { 
     "$oid": "58cdf0023cefa56136afb50f" 
    }, 
    "question": "Who is the best Bob?", 
    "options": [ 
     { 
      "answer" : "answer1", 
      "option": "Bob Dylan", 
      "votes": 2 
     }, 
     { 
      "answer" : "answer2", 
      "option": "Bob Geldof", 
      "votes": 0 
     } 
    ] 
} 

今すぐ簡単に$pushオペレータと$eachを使用してオプションに埋め込まれた文書を追加することができます。

db.collection('questions') 
    .findOneAndUpdate({"_id": questionId}, {$push: { options: { $each: [ { answer: "answer3", option: 'Bob Saget', votes: 0 },{ answer: "answer4", option: 'Bob Marley', votes: 0 } ] } } }) 
1

ない、これはこれを行うための最善の方法ですが、何を行う可能性は変更して、他のオブジェクトからのオプションを追加するために返された文書にObject.assign()を使用して、交換したい文書を見つけるために、最初の実行findOneクエリであれば確認してくださいその文書はreplaceOneを使用して更新されたものです。

col.findOne(
    {_id: mongodb.ObjectId('IdOfObject')}, 
    function(err, doc) { 
    if (err) console.log(err); 
    Object.assign(doc.options, toInsert.options) 

    col.replaceOne(
     {_id: mongodb.ObjectId('IdOfObject')}, 
     doc, 
     function(e, d) { 
     if (e) console.log(e) 
     else console.log('Object Updated.') 
     } 
    ) 
    } 
) 

更新されたオブジェクトは、この

{ _id: 58ce98cbd85b01133c4c3615, 
    question: 'Who is the best Bob?', 
    options: 
    { answer1: { option: 'Bob Dylan', votes: 2 }, 
    answer2: { option: 'Bob Geldof', votes: 0 }, 
    answer3: { option: 'Bob Saget', votes: 0 }, 
    answer4: { option: 'Bob Marley', votes: 0 } } } 
のようになります。
関連する問題