0

Hi I am developing MeteorJS app, I am stuck at updating a sub sub array element.

It is a poll application and I have the following database structure:

Under each question there are options and when a user clicks a button of an option, I want to increment that options votes by one and every user should have one vote right for each question.

From the button, I am passing name and questionId data in order to find the right option to increment vote. I should find the specific question with the questionId and then the specific array with the name under the Options.

Where I am stuck at is I can't find it.

Please help, thanks

Collection Name: Polls

Each Poll has the following structure:

{
    "_id" : "uJtBt8mM2pbTYfwND",
    "createdAt" : ISODate("2017-04-03T22:40:14.678Z"),
    "pollName" : "First Poll",
    "entryOwner" : "gdAHxDrxFuTvYiFt8",
    "question" : [ 
        {
            "name" : "Question number 1",
            "questionId" : "xgYQxGxpwBXaQpjXN",
            "options" : [ 
                {
                    "name" : "John",
                    "votes" : 0
                }, 
                {
                    "name" : "Adam",
                    "votes" : 0
                }, 
                {
                    "name" : "Robert",
                    "votes" : 0
                }
            ]
        }, 
        {
            "name" : "Question number 2",
            "questionId" : "zviwYHHsaATBdG6Jw",
            "options" : [ 
                {
                    "name" : "John",
                    "votes" : 0
                }, 
                {
                    "name" : "Adam",
                    "votes" : 0
                }, 
                {
                    "name" : "Robert",
                    "votes" : 0
                }
            ]
        }
    ],
}

1 Answer 1

1

You can use $and which performs a logical AND operation on an array of two or more expressions.

{ $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }

The first expression here would be to get the question with questionId.

'question.questionId': "xgYQxGxpwBXaQpjXN"

And second expression to specify the object with matching name in options array. To find the object with the name in options array, you can use $elemMatch which allows to specify queries.

{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }

To get the object in options array having name as "John".

'question.options': {
    $elemMatch: {
        name: "John"
    }
}

And finally, use $inc to increase the votes (here by 1). It will get the first matching element (with $).

'question.options.$.votes': 1

Here's the full code:

db.Polls.update({
    $and: [{
            'question.questionId': "xgYQxGxpwBXaQpjXN"
        },
        {
            'question.options': {
                $elemMatch: {
                    name: "John"
                }
            }
        }
    ]
}, {
    $inc: {
        'question.options.$.votes': 1
    }
})
Sign up to request clarification or add additional context in comments.

2 Comments

In Stack Overflow, it's not enough to write code. Please annotate and explain the code.
thank you very much for the explanation, the problem is that when running this code it does not know the question's index therefore it can not update the votes. I have solved this by installing underscore.js library and finding each items index when the button is clicked.

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.