2

The $match expression on mongodb's stitch application does not work properly.

I am trying to set up a simple update trigger that will only work on one field in a collection.

The trigger setup provides a $match aggregation which seems simple enough to set up.

For example if I want the trigger to only fire when the field "online" in a specified collection gets set to "true" I would do:

{"updateDescription.updatedFields":{"online":"true"}}

which for a stitch trigger is the same as:

{$match:{{updateDescription.updatedFields:{online:"true"}}}

The problem is when i try to match an update on a field that is an object.(for example hours:{online:40,offline:120}

For some reason $exists or $in does not work So doing:

{"updateDescription.updatedFields":{"hours":{"$exists":true}}

does not work,neither does something like:

{"updateDescription.updatedFields":{"hours.online":{"$exists":true}}

The $match for the trigger is supposed to work exactly like a normal mongo $match. They just provide one example :

{
  "updateDescription.updatedFields": {
    "status": "blocked"
  }
}

The example is from here: https://docs.mongodb.com/stitch/triggers/database-triggers/

I tried 100's of variations but i can't seem to get it

The trigger is working fine if the match is a specific value like:

{"updateDescription.updatedFields":{"hours.online":{"$numberInt\":"20"}}

and then i set the hours.online to 20 in the database.

  • How do you check whether the trigger works or not ? Also, what is your update command ? – Wan B. Jul 10 '19 at 05:09
  • 1
    @Radu Tarcea what worked for you? And how would you update your solution to work with $or? If for instance you want to match when `hours.online` is either `20` or `10`, how would your solution to work with that? I have a similar problem and I'm using $or but the trigger doesn't match as I want it to. I've posted about it [here](https://stackoverflow.com/questions/62518308/my-or-selector-in-a-database-trigger-match-expression-doesnt-work-at-the-secon). Thanks! – Uche Ozoemena Jun 22 '20 at 16:59
  • Original question, but not exact same https://stackoverflow.com/questions/62518308/my-or-selector-in-a-database-trigger-match-expression-doesnt-work-at-the-secon – user3919920 Jun 22 '20 at 17:10

2 Answers2

2

I was able to have it match items by using an explicit $expr operator or declare it as a single field not an embedded object. ie. "updateDescription.updatedFields.statue": "blocked"

karloluis
  • 209
  • 2
  • 13
  • 1
    how would you update your solution to work with $or? If for instance you want to match when "statue" (or did you mean "status"?) is either "blocked" or "pending", how would you modify your match expression to work with that? I have a similar problem and I'm using $or (without $expr because $or apparently needs to always be the first operator) but the trigger doesn't match as I want it to. I've posted about it [here](https://stackoverflow.com/questions/62518308/my-or-selector-in-a-database-trigger-match-expression-doesnt-work-at-the-secon). Thanks! – Uche Ozoemena Jun 22 '20 at 16:57
2

I struggled with this myself, trying to get a trigger to fire when a certain nested field was updated to any value (rather than just one specific one).

The issue appears to have to do with how change streams report updated fields.

With credit and thanks to MongoDB support, I can finally offer this as a potential solution, at least for simpler cases:

{
    "$expr": {
        "$not": {
            "$cmp": [{
                "$let": {
                    "vars": { "updated": { "$objectToArray": "$updateDescription.updatedFields" } },
                    "in": { "$arrayElemAt": [ "$$updated.k", 0 ] }
                }},
                "example.subdocument.nested_field"
            ]
        }
    }
}

Of course replace example.subdocument.nested_field with your own dot-notation field path.

Robert S.
  • 46
  • 4