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);
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}});