'mongodb set field value using if else during document update

Is there a way in mongodb to use if/else to set a field value during an update. i know that i can use find, to return documents, loop over them, and do if/else check on each and make a new save query for each of the documents.

However, that seems wasteful, if there is a way to update conditionally in one go.

Is it possible to conditionally set a field value, e.g like this

Documents.update(
    {some_condition: true}, 
    {$set: {"status": 
        {$cond: 
              {if  : {"some field": "some condition"}},
              {then:  "value 1"} ,
              {else: "value 2"} 
        } 
    }} 
)

(I know that $cond is used for aggregation, i used it here as an example of what i have in mind.)



Solution 1:[1]

MongoDB doesn't support the sort of conditional update you're looking for. However, you can still do better than using a find, loop, and save approach.

Move the condition check into the update query selector and then issue two updates (one for each case), using {multi: true} to apply the update to all matched docs.

// Start with the "if" update
Documents.update(
    {some_condition: true, "some field": "some condition"}, 
    {$set: {"status": "value 1"}},
    {multi: true},
    function(err, numAffected) {
        // Now do the "else" update, using $ne to select the rest of the docs
        Documents.update(
            {some_condition: true, "some field": {$ne: "some condition"}}, 
            {$set: {"status": "value 2"}},
            {multi: true},
            function(err, numAffected) {
                // All done.
            }
        )
    }
)

Solution 2:[2]

Answer: Yes

It's pretty much possible using the $set stage in the aggregation pipeline

  1. Use $set to compute the conditional value in each record
  2. Use $out to update the records in the collection

Example:

db.collectionname.aggregate(
    [
        {
            $set: {                   //Compute the new value
                'ResultField': {
                    $cond: {
                        if: {
                            $lt: ['$ScoreField', 40]
                        },
                        then: "Fail",
                        else: "Pass"
                    }
                }
            }
        },
        {
            $out: 'collectionname'    //Update the records in collection
        }
    ]
)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JohnnyHK
Solution 2 Alpesh Patil