Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB update with condition

I'm trying to update some field in my collection depending on a condition.

I want to set field active to true if the condition is true and to false otherwise

This is update without condition

db.consent.update( {}, //match all {     $set: {         "active": true     } },  {     multi: true, }  ) 

I would like to add a condition to update like this:

db.consent.update( {}, $cond: {     if: {          $eq: ["_id", ObjectId("5714ce0a4514ef3ef68677fd")]      },     then: {         $set: {             "active": true         }     },     else: {         $set: {             "active": false         }     } },  {     multi: true, } 

)

According to https://docs.mongodb.org/manual/reference/operator/update-field/ there is no $cond operator for update.

What are my options here to execute this update as a single command?

like image 894
q99 Avatar asked Apr 18 '16 15:04

q99


People also ask

Does MongoDB update automatically?

No, there is no such thing (autoupdate) in MongoDB. It must be done with application or script.

Is it possible to update MongoDB field using value of another field?

Starting from MongoDB 4.2 you can perform Updates with an Aggregation Pipeline. An aggregation pipeline enables more expressive updates including calculated fields and references to other field values in the same document.

Which option of the update method creates a new document if no documents match the query to update?

Upsert with update() method: If a document or documents found that matches the given query criteria, then the update() method updates the document/documents. If no document/documents match the given query criteria, then the update() method inserts a new document in the collection.


2 Answers

Starting Mongo 4.2, db.collection.update() can accept an aggregation pipeline, finally allowing the update/creation of a field based on another field:

// { a: "Hello", b: "World" } // { a: "Olleh", b: "Dlrow" } db.collection.update(   {},   [ { $set: { active: { $eq: [ "$a", "Hello" ] } } } ],   { multi: true } ) // { a: "Hello", b: "World", active: true  } // { a: "Olleh", b: "Dlrow", active: false } 
  • The first part {} is the match query, filtering which documents to update (in our case all documents).

  • The second part [ { $set: { active: { $eq: [ "$a", "Hello" ] } } } ] is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline). $set is a new aggregation operator and an alias of $addFields. Then any aggregation operator can be used within the $set stage; in our case a conditional equality check on which depends the value to use for the new active field.

  • Don't forget { multi: true }, otherwise only the first matching document will be updated.

like image 88
Xavier Guihot Avatar answered Sep 23 '22 14:09

Xavier Guihot


You can't.

Mongo doesn't support combining fields, conditionals etc. in the update statement.


See https://stackoverflow.com/a/56551655/442351 below.

like image 41
BanksySan Avatar answered Sep 19 '22 14:09

BanksySan