How to use $and / $or in Match Expression for Atlas Trigger

tldr; Looking for help with the match expression at bottom.

Context: what am I looking to do

I have an Atlas Database Trigger function that checks when a document has been updated, to see if the user has changed their plan, and if so marks this doc to have its computed fields updated.

In the doc…

  • There are 6 fields that tell us the users’ overall plan. If any of those fields change, the plan needs recomputing.
  • There are 2 fields that tells us where the user is in their plan. If those fields change, it might be because the user changed their position in the plan, Or it might be because another Atlas trigger (scheduled weekly) had nudged the user forward.
    • We only want to re-compute the plan if the user changes their position.
    • We can check for whether it was an Atlas Trigger by looking at the “fullDocumentBeforeChange.status” field, and checking it was not a triggering value.

(I appreciate this is probably not the ideal setup, but I’m dealing with migrating functions from a legacy server over, piecemeal, to Mongo Atlas, and there are some aspects I cannot yet change, so I’m doing my best to work within the limits)

What Am I Asking

I can use a conditional within the trigger function to return early if we haven’t matched the conditions we want:

  if ( ( updatedFields.hasOwnProperty('currentWeek') ||
         updatedFields.hasOwnProperty('currentPhase') ) &&
       ( fullDocumentBeforeChange.status !== "moveFwdOneWeek" ) ) {
    updateObj.status = "addWeekListing";
  }
  else if( updatedFields.hasOwnProperty("startDate") ||
       updatedFields.hasOwnProperty("preparation") ||
       updatedFields.hasOwnProperty("offSeason") ||
       updatedFields.hasOwnProperty("preSeason") ||
       updatedFields.hasOwnProperty("inSeason") ||
       updatedFields.hasOwnProperty("taper") ) {
    updateObj.status = "addWeekListing";
  }
  else {
    console.log("Fields that changed aren't relevant to us, exiting."); return;
  }

So I know the field names are correct and the logic of the filter works. What I want to do is to learn how to recreate that, within the Match Expression correctly. I’ve read the match docs, which led me to add $expr in front of my query, but it’s still not filtering correctly. I’d appreciate help with understanding why my current match doesn’t work and how I could adjust it.

{ "$expr":
    { "$or": [
        { "$or": [
            { "updateDescription.updatedFields.startDate": { "$exists": true } },
            { "updateDescription.updatedFields.preparation": { "$exists": true } },
            { "updateDescription.updatedFields.offSeason": { "$exists": true } },
            { "updateDescription.updatedFields.preSeason": { "$exists": true } },
            { "updateDescription.updatedFields.inSeason": { "$exists": true } },
            { "updateDescription.updatedFields.taper": { "$exists": true } }
        ]},
        { "$and": [
            { "$or": [
                { "updateDescription.updatedFields.currentWeek": { "$exists": true }},
                { "updateDescription.updatedFields.currentPhase": { "$exists": true }}
            ]},
            { "fullDocumentBeforeChange.status": { "$ne": "moveFwdOneWeek" } }
        ]}
    ]}
}

Hi @Oliver_Browne ,

Not sure why you can’t use $or or $and as top query operators in a trigger match expression as those are query syntax?

The $expr is for running aggregation syntax in a match…

Thanks
Pavel