I'm creating a web app using Mongoose/MongoDB to store information that will be voted on. I'll be storing usernames and IP addresses with the vote (so voters can update/modify their votes if desired).
Root Question: What's the best way to securely architecture voting in a Mongoose schema?
Currently, my schema looks like this (simplified):
var Thing = new Schema({
title: {
type: String
},
creator: {
type: String
},
options: [{
description: {
type: String
},
votes: [{
username: {
type: String
},
ip: {
type: String
}
}]
}]
});
mongoose.model('Thing', Thing);
While this makes querying the db for any given Thing
super easy, it becomes more problematic for security for obvious reasons - I don't want to be returning out usernames and ip addresses to the browser.
The problem is, I'm not sure which is the best/least painful scenario for securely returning Thing
data to the browser:
Loop through each option in
Thing.options
, then sub-loop through each vote inThing.options[i].votes
to find the vote cast by the user requesting the data, then delete all votes to get rid of other user data. This seems to be very resource intensive, but I couldn't find a way to use indexOf in subarrays (guidance welcome on this one), i.e.Thing.options.votes.indexOf(username)
or something to that effect.Store vote information in the already-existing
User
schema, then have to search through all users for vote data and stick it all together every time I want query a singleThing
. This also seems inefficient/more resource intensive/more complicated than necessary.Create a separate
Vote
schema that stores the data more conveniently, but then adds another database call (one for theThing
, one for theVote
).
This problem is somewhat compounded by the fact that there are different ways to vote, with this being the simplest.
Research...for posterity's sake:
This question addresses voting in databases, but for a relational db, not MongoDB/Mongoose.
This question addresses Mongoose/Node.js app architecture, but nothing about votes.
This NPM Module adds voting to Mongoose schemas, but doesn't quite fit my needs.
This post looks very promising, as the author is sort of doing what I'm describing in point 1 above (see Listing 13 on the author's post), but he still creates a nested loop, starting in line 22 of Listing 13, to loop through each choice/option, then through each vote for each choice/option.