Question

Consider this data

{ 
    "_id" : ..., 
    "array" : [
        { "name" : "value1","flag" : true } ,
        { "name" : "value2","flag" : false }
  ]
}

I would like to toggle the 2nd array element (from false to true)

I know I can update a specific element using the very useful $ positional operator like this:

db.myCollection.update(
    {'array.name':'value2'},
    {
        $set: {
            'array.$.flag':true
        }
    },false,true);  

But is there a way to use the $ positional operator also for the value setting?

e.g. like this?

db.myCollection.update(
    {'array.name':'value2'},
    {
        $set: {
            'array.$.flag':'!array.$.flag' //<--
        }
    },false,true);  
Was it helpful?

Solution

No, it's not possible at the moment. MongoDB doesn't allow expressions in updates that depend on fields in the document. You'll have to get and set in two separate operations.

However, there's a trick to make it in one operation (and therefore atomic). Instead of a boolean value, have an integer. Then even values will represent false, odd ones - true.

// get documents with false flag
db.collection.find({flag: {$mod: [2, 0]}})

// get documents with true flag
db.collection.find({flag: {$mod: [2, 1]}})

// toggle flag
db.collection.update(query, {$inc: {flag: 1}});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top