So what I want to do inside the $set is check if the field exists and then update the value, but only if this field exists. The $cond is very close to what I want to achieve but the problem is I can't stop it from creating the field.
I could filter to get only the existing field, but in this case I would have to update field by field instead of all at the same time, and this would take forever.
const data = await connection.collection("snapshot").updateMany({}, [
{
$set: {
field1: {
$cond: [
{ field1: { $exists: true } },
{ field1: "newValue" },
undefined, // do nothing
],
},
field2: {
$cond: [
{ field2: { $exists: true } },
{ field2: "newValue" },
undefined, // do nothing
],
},
field3: {
$cond: [
{ field3: { $exists: true } },
{ field3: "newValue" },
undefined, // do nothing
],
},
},
},
]);
Am I missing something or is just impossible to do?
I'm using mongo 5.0
CodePudding user response:
Operator $exists
works only in find
, not in Aggregation Pipelines. Checking for "field exists" is not trivial, see Or with If and In mongodb
I assume you like to update documents like { field3: "newValue" }
, your update will do { field3: { field3: "newValue" } }
Over all it would be this one:
connection.collection("snapshot").updateMany({}, [
{
$set: {
field1: {
$cond: [
{ $ne: [{ $type: "$field1" }, "missing"] },
"newValue",
"$$REMOVE" // do nothing
]
},
field2: {
$cond: [
{ $ne: [{ $type: "$field2" }, "missing"] },
"newValue",
"$$REMOVE" // do nothing
]
},
field3: {
$cond: [
{ $ne: [{ $type: "$field3" }, "missing"] },
"newValue",
"$$REMOVE" // do nothing
]
}
}
}
])