好吧,我知道这个问题被问到已经有一段时间了,但是我对上述答案或在类似问题上发布的任何其他答案不满意。所以最后我想出了另一个答案。
首先,如上所述,MongoDB 文档目前被限制为最大 16MB。因此,实现这一点的合乎逻辑的方法是,拥有 2 个不同的集合,一个用于 upvotes,一个用于 downvotes,它将存储 postid 和已投票或否决的用户数组。这将帮助我们分开收藏并有更多的工作空间。为了清楚起见,这里是我使用的模式:
赞成票:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const UpvoteModel = new Schema({
questionid: {
type: Schema.Types.ObjectId,
ref: 'questionsModel'
}
,
votes: [{
user: {
type: Schema.Types.ObjectId,
ref: 'users'
}
}]
})
module.exports = Upvote = mongoose.model('upvotes', UpvoteModel)
对于否决票:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const DownvoteModel = new Schema({
questionid: {
type: Schema.Types.ObjectId,
ref: 'questionsModel'
}
,
votes: [{
user: {
type: Schema.Types.ObjectId,
ref: 'users'
}
}]
})
module.exports = Downvote = mongoose.model('downvotes', DownvoteModel)
帖子收集(或本例中的问题):
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const QuestionsSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
title: {
type: String,
required: true
},
description: {
type: String
},
voteCount: {
type: Number
},
votes: [{
user: { type: Schema.Types.ObjectId }
}],
views: [{
user: { type: Schema.Types.ObjectId }
}],
answers: [{
user: { type: Schema.Types.ObjectId },
answer: {
type: String
},
date: {
type: Date,
default: Date.now
}
}],
date: {
type: Date,
default: Date.now
}
})
module.exports = Question = mongoose.model('questionsModel', QuestionsSchema)
每次创建帖子/问题时,帖子/问题 id 都会存储在 upvote 和 downvote 表中,然后如果用户单击 upvote 或 downvote,您需要将该用户添加到该特定表中,然后去更新 post/question 中的 voteCount桌子。
帖子/问题路线:
router.post('/upvote', (req, res) => {
Upvote.findOne({ questionid: req.body.params.questionid })
.then(oneVote => {
if (oneVote.votes.filter(user => req.body.params.userid).length === 1) {
Question.updateOne({ _id: req.body.params.questionid },
{ $inc: { voteCount: -1 } })
.then(() => {
Upvote.updateOne({
questionid: req.body.params.questionid,
},
{
$pull: {
votes: { user: ObjectId(req.body.params.userid) }
}
})
.then(() => console.log('decrement by -1'))
}
)
.catch(err => console.log(err))
}
else if (oneVote.votes.filter(user => req.body.params.userid).length === 0) {
Upvote.findOneAndUpdate({
questionid: req.body.params.questionid,
'votes.user': { $ne: ObjectId(req.body.params.userid) }
},
{
$push: {
votes: { user: ObjectId(req.body.params.userid) }
}
},
{ useFindAndModify: false }
)
.then(oldupvote => {
Downvote.findOne({ questionid: req.body.params.questionid })
.then(downvote => {
if (downvote.votes.filter(user => req.body.params.userid).length > 0) {
Downvote.updateOne({
questionid: req.body.params.questionid,
},
{
$pull: {
votes: { user: ObjectId(req.body.params.userid) }
}
})
.then(() => {
Question.updateOne({ _id: req.body.params.questionid },
{ $inc: { voteCount: 2 } })
.then(() => console.log('increment by 2')
)
.catch(err => console.log(err))
})
.catch(err => console.log(err))
}
else {
Question.updateOne({ _id: req.body.params.questionid },
{ $inc: { voteCount: 1 } })
.then(() => console.log('increment by 1')
)
.catch(err => console.log(err))
}
})
.catch(err => console.log(err))
})
}
})
.catch(err => console.log(err))
})
否决路线:
router.post('/downvote', (req, res) => {
Downvote.findOne({ questionid: req.body.params.questionid })
.then(oneVote => {
if (oneVote.votes.filter(user => req.body.params.userid).length === 1) {
Question.updateOne({ _id: req.body.params.questionid },
{ $inc: { voteCount: 1 } })
.then(() => {
Downvote.updateOne({
questionid: req.body.params.questionid,
},
{
$pull: {
votes: { user: ObjectId(req.body.params.userid) }
}
})
.then(() => console.log('increment by 1'))
.catch(err => console.log(err))
}
)
.catch(err => console.log(err))
}
else if (oneVote.votes.filter(user => req.body.params.userid).length === 0) {
Downvote.findOneAndUpdate({
questionid: req.body.params.questionid,
'votes.user': { $ne: ObjectId(req.body.params.userid) }
},
{
$push: {
votes: { user: ObjectId(req.body.params.userid) }
}
},
{ useFindAndModify: false }
)
.then(oldownvote => {
Upvote.findOne({ questionid: req.body.params.questionid })
.then(upvote => {
if (upvote.votes.filter(user => req.body.params.userid).length > 0) {
Upvote.updateOne({
questionid: req.body.params.questionid,
},
{
$pull: {
votes: { user: ObjectId(req.body.params.userid) }
}
})
.then(() => {
Question.updateOne({ _id: req.body.params.questionid },
{ $inc: { voteCount: -2 } })
.then(() => console.log('decrement by -2')
)
})
.catch(err => console.log(err))
}
else {
Question.updateOne({ _id: req.body.params.questionid },
{ $inc: { voteCount: -1 } })
.then(() => console.log('decrement by -1')
)
.catch(err => console.log(err))
}
})
.catch(err => console.log(err))
})
// .then(() => {
// Upvote.findOne({ questionid: req.body.params.questionid })
// .then(updatedupvote => console.log(updatedupvote))
// })
.catch(err => console.log(err))
}
})
.catch(err => console.log(err))
})
This answer is posted for future reference if anyone is looking for a similar answere, here it is.