部分更新具有多个值Express.js MongoDB的嵌套对象

时间:2017-03-19 13:53:13

标签: node.js mongodb express

首先,我已阅读部分解决此问题的this stack overflow entry,但我需要动态添加多个条目,并且无法将答案应用于此问题。

我有一个包含民意调查的网站(使用快递和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");
  })
编辑:我刚刚意识到他的错误,所以我甚至无法正确地编写答案。但是,为了清楚起见,我将在此留下。

但我需要做的是使用1-3个可能的新选项(取决于用户想要的内容)动态更新嵌套的options对象,并将预先存在的数据单独留在options中宾语。在上面的示例代码中,我希望从answer3插入answer4toInsert

我是Node和MongoDB的新手,我的想法是“嘿,我可以把它通过一个for loop”似乎是一个坏主意,即使我可以让它工作。

2 个答案:

答案 0 :(得分: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
        }
    ]
}

现在,您可以使用$each $push运算符轻松地将嵌入文档添加到选项中。

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

答案 1 :(得分:1)

不确定这是否是执行此操作的最佳方式,但您可以执行的操作是首先运行findOne查询以查找要修改的文档,然后对返回的文档使用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 } } }