2 / 6
May 2024

In an aggregation stage I want to set several fields in case a condition results to true like this:

{ $set: { $cond: { if: { $ne: ["$isLastReceiveTime", null] }, then: { complete: true, completedTime: "$$NOW" }, else: { complete: "$$REMOVE", completedTime: "$$REMOVE" } } } }

But that does not work since $set expects a field name and not an operator like $cond

Currently I’m doing it this way:

{ complete: { $cond: { if: { $ne: ["$isLastReceiveTime", null] }, then: true, else: "$$REMOVE" } }, completedTime: { $cond: { if: { $ne: ["$isLastReceiveTime", null] }, then: "$$NOW", else: "$$REMOVE" } } }

But this is really not nice and maintainable …

Hi @Frank_Numrich1, Welcome back,

I think there is no any better approach, but below is the same just a short-hand approach of the $cond operator.

{ $set: { completedTime: { $cond: ["$isLastReceiveTime", "$$NOW", "$$REMOVE"] }, complete: { $cond: ["$isLastReceiveTime", true, "$$REMOVE"] } } }

Hi @turivishal ,

that’s what I feared - so I have to stay with this …
In fact I already knew the short form but wasn’t aware that I don’t need the $ne statement which makes it much more readable.

Thanks and best regards,
Frank

In fact my condition is slightly more complex than in my example which I made easy to have the focus on the question …

The real statement looks like this:

{ complete: { $cond: [{$and: ["$isLastReceiveTime", {$eq: [{$add: [{$max: "$mjrCounter"}, 1]}, {$size: "$mjrCounter"}]}]}, true, "$$REMOVE"] }, completedTime: { $cond: [{$and: ["$isLastReceiveTime", {$eq: [{$add: [{$max: "$mjrCounter"}, 1]}, {$size: "$mjrCounter"}]}]}, "$$NOW", "$$REMOVE"] } }

It surprises me that it is not possible to write the statement this way:

if <condition> <action_1> <action_2>

but instead have to write

<action_1> if <condition> <action_2> if <condition>

No one would write code this way …

5 months later

The problem is not exactly the same because my need to set several fields conditionally was one level deep, I found that $mergeObjects would do the trick:

{ $set: { myProp: { $mergeObjects:[ "$myProp", $cond: [ $ne: ["$isLastReceiveTime", null], { complete: true, completedTime: "$$NOW" }, { complete: "$$REMOVE", completedTime: "$$REMOVE" } ] ] } } }

For your use case probably a combination of $replaceRoot and $$ROOT would achieve the same effect.