How to trigger a function on any change on a field with a change stream in Atlas?

Hello,

I try to set up a database trigger in Atlas and run into a problem.

This Match expression will fire a DB Trigger when the field status is updated to blocked

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

I like to fire a trigger when the field status is updated to blocked OR the field name is updated to any value as in simply changed.

How can I reflect this in a Match Expression in Atlas?

Hi, few things here,

Firstly, its likley that you want the above to be:

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

Since this matches on a document that has this field set. Your expression only matches changes that ONLY update that field.

For what you want, I think you want your match expression to be this:

{
  $or: [
    {"updateDescription.updatedFields.status": "blocked"},
    {"updateDescription.updatedFields.name": {$exists: true}},
  ]
}

Let me know if this works!
Tyler

Thanks @Tyler_Kaye

This will fire execute the function when:

  • the field status is updated to blocked OR
  • the field name exists

But I need:
This will fire execute the function when:

  • the field status is updated to blocked OR
  • the field name underlies any change this implies the existence but adds the constraint that the existing value is changed

Sorry, I am not quite sure I follow this. Do you mind clarifying?

The excuse is on my side.

I want to trigger the function:

  • either when the field status is updated “blocked”
  • or I want to trigger the function when the field name is changed. So in case name was “abc” and is updated to “efg” this would trigger the function. If name is “abc” and is not changed then nothing should happen.

The above mentioned version
“updateDescription.updatedFields.name”: {$exists: true}}
would afaik not trigger the function on the change from “abc” to “efg” since the field already exists.

I think that this is exactly what you want actually. This is a query on the “Change Event” (See here: https://www.mongodb.com/docs/manual/reference/change-events/update/#description)

The UpdateDescription only has the fields that are actually modified, so the query I gave above does the following:

  1. If the field “status” is updated and it is updated to the value “blocked”
  2. OR if the field “name” is updated (in any way)

Note that this will not catch the field “name” being removed entirely (you would need to add another clause to the OR on the “removedFields” section of the UpdateDescription

Let me know if this works for you!
Tyler

Hello @Tyler_Kaye
thanks a lot! I can test this next monday.
Also many thanks for the link, it solved a misconception on my side concerning the “mechanics” of the change streams. Now I am 99.9% sure that you solved it already with your initial answer. I’ll update on monday.
Regards,
Michael

Hello @Tyler_Kaye
thanks a lot your code answered the question. Plus this link on the update Change Event

The buildin Editor in Atlas is a little bit picky, so I had to surround the $or and $exists with quotation marks.

May I know where do we pass this criteria for firing the trigger. Is it in the function that we write to associate a trigger?

Match expressions are passed directly to the MongoDB Change Stream API: https://www.mongodb.com/docs/manual/changeStreams/

It is important to understand Change Events and their format before trying to craft one:

However, I generally would advise you to avoid a match expression until your load becomes high enough that it is a concern. Instead, I think it is worth considering just receiving all events to the cluster and you can build your logic directly into the function of what you want to do when the UpdateDescription containts certain fields

1 Like