【发布时间】:2018-10-06 00:54:55
【问题描述】:
我正在尝试更新 mongoDB 中包含嵌套数组的文档。
情况如下:
我有一个 newsItem 模型,它可以包含一个 poll 对象。这个投票对象有:title、totalVotes 和 options。 option 是一个对象数组,这些对象包含:optionName 和 optionVotes。在这些对象中的每一个中。 optionVotes 是一个数组,其中包含对其投票的用户的 ID。 (因为我想跟踪谁投票了什么以及有多少我想阻止两次投票)
所以它应该看起来像这样:
{
"_id" : ObjectId("5bb7487727430319f5c18495"),
"poll" : {
"totalVotes" : 0,
"title" : "test",
"options" : [
{
"optionName" : "Burgers",
"optionVotes" : []
},
{
"optionName" : "Pizza",
"optionVotes" : []
},
{
"optionName" : "Fish",
"optionVotes" : []
},
{
"optionName" : "BBQ",
"optionVotes" : []
},
{
"optionName" : "Soup",
"optionVotes" : []
},
{
"optionName" : "Pasta",
"optionVotes" : []
}
]
}
}
我现在要做的是,每当调用 api 路由 /news/votes/:id 时,它都会使用 :id 更新 newsitem 并将用户 id 放入给定的投票选项中。 (在体内) 所以在请求中我有:用户 id 和投票的 optionName
这是我目前得到的,对我不起作用:
exports.vote = (req, res) => {
News.findOneAndUpdate({ _id: req.params.id }).exec((err, newsItem) => {
let tempItem = newsItem
for (let i = 0; i < tempItem.poll.options.length; i++) {
if (tempItem.poll.options[i].optionName === req.body.optionName) {
tempItem.poll.options[i].optionVotes.push(req.user._id)
}
}
console.log(tempItem.poll.options[0])
tempItem.save(err => {
if (!err) {
return res.status(200).send()
}
})
})
}
奇怪的是,例如,当我这样做时:
tempitem.poll.title = '新标题' tempitem.save()
那么标题确实会在数据库中更新! 代码中的 console.log 确实输出了正确的对象..
我也尝试过使用更标准的方式:
findOneAndUpdate({ _id: req.param.id }, {$addToSet: {.....}}).exec(...)
但那样我实际上不知道如何从数组中获取具有特定键的对象,然后更新该对象的一部分。
我正在考虑的其他 2 个选项:
- 将整个投票对象提取到另一个文档,然后使用 在 newsItem 中引用 .. 但这并不能解决问题 要么(对 SQL 也有感觉)
- 不将投票用户数组放入每个投票选项中,而只是让 所有投票的人的用户数组。 --> 缺点:我不能看 谁对什么投了赞成票..
【问题讨论】:
标签: javascript node.js mongodb mongoose mongoose-schema