Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to toggle a Boolean field in an Array element in MongoDB?

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);  
like image 613
Eran Medan Avatar asked May 08 '12 21:05

Eran Medan


People also ask

How do I toggle Boolean values in MongoDB?

If you are using MongoDB 4.2, you can use aggregation operators in your update statement, like: . findOneAndUpdate({_id: day.id},[{$set:{present:{$eq:[false,"$present"]}}}]); That will set present to true if it is false, and to false if it is any other value.

How do I pop a specific element from an array in MongoDB?

To remove an element, update, and use $pull in MongoDB. The $pull operator removes from an existing array all instances of a value or values that match a specified condition.

How do you update an array element in MongoDB?

Learn how to update array fields in documents in MongoDB collections. You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.

How is Boolean stored in MongoDB?

Boolean is a native field type in BSON (MongoDB's server-side storage format, aka "Binary JSON"). Booleans use less storage than an integer or string and avoid any unexpected side effects of comparison.


1 Answers

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}});
like image 199
Sergio Tulentsev Avatar answered Oct 17 '22 16:10

Sergio Tulentsev