使用多个值Express.js MongoDB部分更新嵌套对象

首先,我已经阅读了这个部分解决这个问题的堆栈溢出条目 ,但是我需要dynamic地添加多个条目,并且不能将答案应用于这个问题。

我有一个有民意调查的网站(使用express和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 } } } 

所以用这个条目,用户最多可以添加三个附加的答案选项。

当我硬编码的附加答案的名称(例如在这个数据库的例子答案3),我可以更新嵌套的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"); }) 

编辑:我刚刚意识到他也有一个错误,所以我甚至不能硬编码正确的答案。 不过,为了清晰起见,我将在此留下。

但是我需要做的是dynamic地更新这个嵌套的options对象,使用1-3个可能的新选项(取决于用户想要的),并将options对象中原有的数据单独保留。 在上面的示例代码中,我想插入来自toInsert answer3toInsert

我对Node和MongoDB非常陌生,我的想法是“嘿,我可以通过一个for loop ”,即使我可以把它工作,似乎也是一个坏主意。

通过使用选项embedded的数组文件replace答案文档,您可以达到目标。

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

现在你可以通过使用$each $push操作符来轻松地将embedded式文档添加到选项中。

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

不知道这是否是最好的办法做到这一点,但你可以做的是先运行findOne查询find你想要修改的文件,然后在返回的文件上使用Object.assign()从其他对象添加选项,然后用更新一个使用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 } } }