avatarhzh
avatarhzh

Reputation: 2373

Mongodb Increment value inside nested array not working

I'm building a app where you can vote on user submitted polls. Here's the schema for my polls:

const pollSchema = new Schema({
    userID: String,
    pollQuestion: String,
    pollOptions: [
        {
            name: String,
            quantity: Number
        }
    ]
})

This is the express route that handles incrementing the quantity of a poll option:

app.put('/vote', (req, res) => {
    Poll.update(
        {
            id: req.body.id,
            'pollOptions.name': req.body.selection
        },
        { $inc: { 'pollOptions.$.quantity': 1 } }
    ).then(updatedPoll => {
        console.log('poll', updatedPoll)
        res.send(updatedPoll)
    })
})

here req.body.selection is the option that the user has chosen to vote for.

I basically want the quantity of the user's chosen option to increment by one. This way of updating the database I derived from the answer to this question

When I send a request to this route I get some very unexpected behaviour. For one thing, the database doesn't get updated or changed in any way. The second thing is the updatedPoll is a really bizarre object. Here's what i get from the console.log:

poll { n: 0,
  nModified: 0,
  opTime: 
   { ts: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1510783687 },
     t: 1 },
  electionId: 7fffffff0000000000000001,
  ok: 1 }

The one thing I've tried is include { new: true } as a third parameter after the object with the $inc operator. I doesn't change anything. Can someone please help with this issue?

Upvotes: 0

Views: 966

Answers (1)

avatarhzh
avatarhzh

Reputation: 2373

Thanks to Neil Lunn in the comments, changing my route to the following worked for me:

poll.put('/vote', (req, res) => {
    Poll.findOneAndUpdate(
        {
            _id: req.body.id,
            pollOptions: {
                $elemMatch: { name: req.body.selection }
            }
        },
        { $inc: { 'pollOptions.$.quantity': 1 } },
        { new: true }
    ).then(poll => {
        res.send(poll)
    })
})

Upvotes: 1

Related Questions