Reputation: 1021
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?
Upvotes: 54
Views: 120807
Reputation: 61666
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.updateMany(
{},
[ { $set: { active: { $eq: [ "$a", "Hello" ] } } } ]
)
// { 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.
Upvotes: 76
Reputation: 28510
You can't.
Mongo doesn't support combining fields, conditionals etc. in the update statement.
See https://stackoverflow.com/a/56551655/442351 below.
Upvotes: 14
Reputation: 734
We can do it using aggregation pipeline. Here i am updating male to female and female to male.
db.customer.updateMany(
{ },
[
{ $set: { gender: { $switch: {
branches: [
{ case: { $eq: [ "$gender", 'male' ] }, then: "female" },
{ case: { $eq: [ "$gender", 'female' ] }, then: "male" }
],
default: ""
} } } }
]
)
Upvotes: 35
Reputation: 346
db.consent.update(
{
//YOUR CONDITIONAL HERE TO APLLAY UPDATE ONLY IF CONDITIONAL HAPPEN, SO THE "active": true WILL BE APPLY.
},
{
$set: {
"active": true,
"active2": FALSE,
}
},
{
multi: true,
}
)
Upvotes: 5
Reputation: 718
Of course you can.... by running 2 queries
db.collection.update({condition}, { $set: { state } }, { multi: true });
db.collection.update({!condition}, { $set: { state } }, { multi: false });
for your example case
db.consent.update(
{"_id": ObjectId("5714ce0a4514ef3ef68677fd")},
{ $set: { "active": true } });
db.consent.update(
{"_id": {$ne: ObjectId("5714ce0a4514ef3ef68677fd")}},
{ $set: { "active": false } },
{ multi: true });
Upvotes: 9
Reputation: 8978
You can update MongoDB document conditionally using findAndModify() or findOneAndUpdate() if you have MongoDB version 3.2+
Upvotes: 13