Mongo data modeling/updates for voting (up and down)
There is an example on voting data model/update queries in Mongo:
http://www.mongodb.org/display/DOCS/MongoDB+Data+Modeling+and+Rails#MongoDBDataModelingandRails-AtomicUpdatesHowever I need both up and down votes (basically, one person can either cast up vote or down vote). Also, I want for voter to be able to change his mind and change upvote to downvote or vice-versa (so the list of voters and total number does not fit).
What would be the best data model and corresponding update call?
I see two possibilities, either do a
'votes': [{ 'user_id' : ... , 'vote': ±1 }]
or
'upvoters': [...]开发者_StackOverflow社区, 'downvoters': [...]
But I can't make an update query for the first one yet, and second one looks a bit weird (though it may be just me).
Seems much simpler to use the second schema.
Document: { name: "name",
upvoters: [name1, name2, etc],
downvoters: [name1, name2, etc],
}
To get total votes you can get the doc and use doc.upvoters.length-doc.downvoters.length (start each document with upvoters and downvoters arrays being [ ])
To record any upvote by User "x" on item "c" just do:
db.votes.update({name:"c"},{$addToSet:{upvotes:"x"},$pull:{downvotes:"x"}})
This is atomic and it has advantage of doing the same thing even if you run it 10 times. It also spares you from having to check if "x" already voted for "c" and which way.
To record downvote just reverse it:
db.votes.update({name:"c"},{$addToSet:{downvotes:"x"},$pull:{upvotes:"x"}})
First schema looks like good. Second schema is hard because when user click upvote and than downvote you need add userId to 'upvoters' that to 'downvoters' and remove from 'upvoters' and vice versa.
I suppose votes it nestead collection of some document(suppose it questions).
db.questions.update({votes.userId: .. },{ $set : { votes.$.vote : 1 } });//upvote
db.questions.update({votes.userId: .. },{ $set : { votes.$.vote : -1 } });//down
And seems you need create extra field inside of questions collection to calculate sum of up/down votes:
db.questions.update({_id: .. },{ $inc : { votesCount : 1 } }); //up vote
db.questions.update({_id: .. },{ $inc : { votesCount : -1 } }); // down vote
If you need add new user to array of votes use
Possitional operator.
精彩评论