If a user deactivates their account we need to perform some updates to different collections. One of these collections is adding an end_date to their mandate and set a stop reason to the assigned EANs (it's a code for an energy meter) which do not have a stop reason already.
Is it possible to do this update in one call?
The current call looks like this but the end_date and stop_reason of the assigned_eans inside the tariffs object may not be updated when a value is already set.
await EnergyMandate.updateMany([{ leadID, end_date: { $exists: false } }, {
$set: {
end_date: Math.floor(Date.now()),
stop_reason: 'deactivated_account',
'tariffs.electricity.assigned_eans.$[].end_date': Math.floor(Date.now()),
'tariffs.electricity.assigned_eans.$[].stop_reason': 'deactivated_account',
'tariffs.gas.assigned_eans.$[].end_date': Math.floor(Date.now()),
'tariffs.gas.assigned_eans.$[].stop_reason': 'deactivated_account',
}
}], { session });
[EDIT 1] Updated query based on @nimrod serok's answer
const mandates = await EnergyMandate.updateMany({ leadID, end_date: { $exists: false } }, {
$set: {
end_date: Math.floor(Date.now()),
stop_reason: 'deactivated_account',
'tariffs.electricity.assigned_eans': {
$map: {
input: "$tariffs.electricity.assigned_eans",
in: {
$mergeObjects: [
"$$this",
{
end_date: { $ifNull: ["$$this.end_date", Math.floor(Date.now())] },
stop_reason: { $ifNull: ["$$this.stop_reason", 'deactivated_account'] }
}
]
}
}
},
'tariffs.gas.assigned_eans': {
$map: {
input: "$tariffs.gas.assigned_eans",
in: {
$mergeObjects: [
"$$this",
{
end_date: { $ifNull: ["$$this.end_date", Math.floor(Date.now())] },
stop_reason: { $ifNull: ["$$this.stop_reason", 'deactivated_account'] }
}
]
}
}
}
}
});
CodePudding user response:
If I understand correctly you can use update pipeline with $map
and $ifNull
for this:
db.collection.updateMany(
{leadID, end_date: {$exists: false}},
[{$set: {
end_date: ISODate("2022-09-20T18:00:00.000Z"),
stop_reason: "deactivated_account",
"tariffs.electricity.assigned_eans": {
$map: {
input: "$tariffs.electricity.assigned_eans",
in: {
end_date: {$ifNull: [
{$cond: [
{$eq: ["$$this.end_date", ""]},
ISODate("2022-09-20T18:00:00.000Z"),
"$$this.end_date"
]}, ISODate("2022-09-20T18:00:00.000Z")
]},
stop_reason: {$ifNull: [
{$cond: [
{$eq: ["$$this.stop_reason", ""]},
"deactivated_account",
"$$this.stop_reason"
]}, "deactivated_account"]}
}
}
},
"tariffs.gas.assigned_eans": {
$map: {
input: "$tariffs.gas.assigned_eans",
in: {
end_date: {$ifNull: [
{$cond: [
{$eq: ["$$this.end_date", ""]},
ISODate("2022-09-20T18:00:00.000Z"),
"$$this.end_date"
]}, ISODate("2022-09-20T18:00:00.000Z")
]},
stop_reason: {$ifNull: [
{$cond: [
{$eq: ["$$this.stop_reason", ""]},
"deactivated_account",
"$$this.stop_reason"
]}, "deactivated_account"
]}
}
}
}
}
}
])
See how it works on the playground example