我是MongoDB的新手,我正在尝试实现upvote / downvote系统,以便用户可以对我的应用程序中的评论进行投票。
我如何设置系统,是用户通过按应用程序中的upvote或downvote按钮通过AJAX发送POST请求,该按钮包含一个布尔值“ upvote”(如果为true,则为upvote;如果为true,则为downvote)。 false(此代码有效,所以我没有包含它)。请求到达服务器后,服务器将检查用户投票的评论是否已经包含投票。如果不是,则服务器向该评论的“投票”数组添加一个投票,并增加或减少该评论的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();
});
}
});
此外,我认识到这段代码可能效率不高,我也很感谢这方面的任何技巧。
答案 0 :(得分:1)
与其先做findOne()
,然后再做findOneAndUpdate()
,不如将findOneAndUpdate()
与upsert option一起使用,会更好。这样,您就不需要在回调中使用额外的if语句。
我还建议不要将votes
作为数组存储在ReviewSchema
中。该数组可以无限增长,因为任何数量的用户都可以对Review
进行投票,这意味着审阅文档可能会变得庞大而笨拙。我建议改为使用映射集合。