MongoDB/Node- Check if a document within a collection has a specific field

Hey again, I’m still stuck on the voting app challenge. This time I want to track which IP address has voted on which question (to stop them voting more than once) but I’m unsure how to specifically check if the question document has the IP address or not.

I’m using the MongoDB node.js driver.

First, I store their IP in the question document in the questions collection:

  var questionId = ObjectId(req.body._id);

  var ip = req.headers['x-forwarded-for'] ||
       req.connection.remoteAddress ||
       req.socket.remoteAddress ||
       req.connection.socket.remoteAddress;
  ip = ip.replace("::ffff:", "").replace(/\./g, "");

  db.collection('questions')
  .findOneAndUpdate({"_id": questionId}, {$set : {[ip] : true} }, (err, result) => {
    if (err) return res.send(err)
  }) 

However, I want to verify that the IP does not already exist in the question’s document.``

So I want to check if {’_id’: questionId} has: {[ip]: true} or even ip as a field.

The database entry looks like this (edited for clarity):

{
    "_id": {
        "$oid": "58caeb3402f11c2d66dc3f41"
    },
    "question": "Metallica or Megadeth?",
    "answer1": "Metallica",
    "answer2": "Megadeth",
    "answer1_votes": 14,
    "answer2_votes": 11,
    "127001": true
}

As we can see 127.0.0.1 has voted already, so I would want to stop that user voting again on that question.

I’m doing it with the IP as I want non-registered users to be able to vote.

I’m sure it’s very simple, but I’m lost completely.

First - I usually recommend to use mongoose instead of native mongodb driver.

Second - in my Voting app I had an array of IPs in the poll object. After retrieving the poll I checked if the array has the current IP. If yes - send error message, if no - push current IP to the array, update vote counter and then update db.

I found it easier to do in two steps than to try to write some convoluted query (although ideally you should minimize the db requests). Also it would be better to make the array of IPs a separate collection, but for this use case array inside the poll is good enough.

And third - Slipknot :wink:

EDIT.
Found this SO thread, looks like it is what you need: http://stackoverflow.com/questions/17039018/how-to-use-a-variable-as-a-field-name-in-mongodb-native-findone/17039560

Also check mongodb query selector $exists

2 Likes