1

This is my model:

const mongoose = require("mongoose");
const shortid = require("shortid");
const { v4: uuidv4 } = require("uuid");

const PollSchema = new mongoose.Schema({
  id: {
    type: String,
    default: shortid.generate
  },
  question: {
    type: String
  },
  options: [
    {
      option: {
        type: String
      },
      votes: {
        type: Number,
        default: 0
      },
      uid: {
        type: String,
        default: uuidv4
      }
    }
  ],
  created: {
    type: Date,
    default: Date.now
  }
});

module.exports = Poll = mongoose.model("poll", PollSchema);

I need to search for the poll by uid and increment the votes number by 1. This is what I've tried and it doesnt work:

Poll.findOneAndUpdate(
  { options: { $elemMatch: { uid: optionId } } },
  { $inc: { "options.$.votes": 1 } },
  { new: true }
);

nothing updates in the database I'm not sure why. The var of the search uid that I supply is optionId.

1
  • You could try this out Poll.findOneAndUpdate({ "options.uid": optionId }, { $inc: { "options.$.votes": 1 }, { new: true } }) Commented Jun 10, 2020 at 5:51

2 Answers 2

2

For 1 Level nesting its not necessary to use arrayFilters so this should work:

Poll.findOneAndUpdate({ _id: yourId, "options.uid": optionId }, { $inc: { "options.$.votes": 1 }, { new: true } })
Sign up to request clarification or add additional context in comments.

3 Comments

This also worked and had to perform less computation.
That is true. I believe that arrayFilters are great when it comes to arrays in general as you can very easily modify the code in order to write a reusable function that will take dynamic values, instead of predefined ones. For example, he could now just replace votes with ${req.body.votes} and options with ${req.body.field}. I understand it is beyond the scope of the question, I just thought it is worth mentioning.
arrayFilters is good if you search in a array, that is in an another array that means more then 1 level of nesting. Yes you could go with arrayFilters but id like to keep it simple
1

Can you please try this code:

Poll.findOneAndUpdate(
  { _id: id }, //that is poll id
  {
    $inc: { [`options.$[outer].votes`]: 1 }
  },
  {
    arrayFilters: [{ "outer.uid": optionId }],
    new: true
  },
  function(err, poll) {
    if (!err) {
      console.log(poll);
    }
  }
);

3 Comments

I tried it and it logs the poll but it still doesnt increment the votes. Also, what is outer?
"outer" is just a reference for arrayFilters. You could name it any other way really. Edited the answer. Can you try it now, please?
Glad to hear. Had a typo initially, sorry for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.