我是MongoDB的新手,我正在尝试实施一个upvote / downvote系统,以便用户可以在我的应用程序中对评论进行投票 .
我如何设置我的系统是用户通过按下应用程序中的upvote或downvote按钮通过AJAX发送POST请求,其中包含一个布尔“upvote”,如果为true则为upvote,如果为false则为downvote(此为代码工作,所以我没有包括它) . 一旦请求到达服务器,服务器就会检查用户投票的评论是否已包含投票 . 如果不是,则服务器向评论的“投票”数组添加投票,并递增或递减该评论的voteBalance属性 . 如果在该评论的“投票”数组中已经存在投票,那么它应该:
1)如果现有投票的upvote属性与新投票不同,则修改它,然后相应地修改voteBalance,或者
2)如果现有投票的upvote属性与新投票属性相同,则删除现有投票,然后相应地修改voteBalance
我插入新投票的代码工作正常,但我遇到的问题是,当投票已经存在时,我无法弄清楚如何使其工作 . 在下面的服务器端代码中,底部附近的else语句是我试图从上面处理案例1),但它不起作用 . 那么我怎样才能使这两种情况起作用呢?
这是我的评论架构:
var ReviewSchema = new mongoose.Schema({
authorID: {
type: String,
required: true,
},
movieID: {
type: Number,
required: true,
},
date: {
type: Number,
required: true
},
username: {
type: String,
required: true
},
score: {
type: Number,
required: true
},
text: {
type: String
},
voteBalance: {
type: Number,
required: true,
default: 0
},
votes: [{
voterID: {
type: String,
required: true,
},
upvote: {
type: Boolean,
required: true
}
}],
comments: [{
commenterID: {
type: String,
required: true,
},
text: {
type: String,
required: true
},
date: {
type: Number,
required: true
}
}]
},{collection: 'reviews'});
这是我用来在服务器上创建和更新投票的代码:
Review.findOne({_id: new ObjectID(reviewID), votes: { $elemMatch: { voterID: req.session._id }}}, function(err, review) {
if (err) {
console.log(err);
res.status(500).send();
}
//If vote was not found (or if review was not found), create vote
if (!review) {
if (upvote) {
var update = {$addToSet: {votes: {voterID: req.session._id, upvote}}, $inc : {voteBalance : 1}};
}
else {
var update = {$addToSet: {votes: {voterID: req.session._id, upvote}}, $inc : {voteBalance : -1}};
}
Review.findOneAndUpdate({_id: new ObjectID(reviewID)}, update, function(err, review) {
if (err) {
console.log(err);
return res.status(500).send();
}
res.status(200).send();
});
}
//If vote was found, update
else {
if (upvote) {
var update = {$set: { 'votes.$.upvote': upvote }, $inc : {voteBalance : 1}};
}
else {
var update = {$set: { 'votes.$.upvote': upvote }, $inc : {voteBalance : -1}};
}
Review.findOneAndUpdate({_id: new ObjectID(reviewID), 'votes.$.voterID': req.session._id}, update, function(err) {
if (err) {
console.log(err);
return res.status(500).send();
}
res.status(200).send();
});
}
});
此外,我认识到这段代码可能没有那么高效,我也很感激这方面的任何提示 .
1 回答
而不是
findOne()
然后findOneAndUpdate()
,你最好使用findOneAndUpdate()
与upsert option . 这样你在回调中就不需要额外的if语句了 .我还建议不要将
votes
存储为ReviewSchema
中的数组 . 该数组可以不受限制地增长,因为任何数量的用户都可以对Review
进行投票,这意味着审阅文档可能会变得庞大且笨拙 . 我建议使用映射集合 .