Does free tier MongoDB Atlas M0 support trigger creation?

I’m trying to create a trigger in MongoDB Atlas M0, but can’t link data source for it to work. Does MongoDB Atlas M0 supports trigger creation?

Hi @Linda_Peng - Welcome to the community!

You should be able to create triggers and link them with a M0 tier cluster data source. Are you trying to create a Database trigger?

If so, what is the issue you are encountering when trying to link the data source? (i.e. No options, greyed out dropdown menus, error messages?)

Fwiw my own M0 test environment has 2 database triggers associated with it.

Regards,
Jason

When I try to link the data source, it is sort of greyed out with a red circle to prevent the linking. In the next section of trigger source details, I can select the cluster though. I don’t know if this is supposed behavior where link button doesn’t link. I’m not seeing expected behavior after defining the function, so I’m not sure if it’s linking issue preventing the trigger working or code issue itself.

I checked the trigger status is enabled so it maybe created already without the link button working. After I define the function and click ‘run’, it generated following output:

result:
{
“$undefined”: true
}
result (JavaScript):
EJSON.parse(‘{“$undefined”:true}’)

What does that mean? The trigger is not working as expected. So the above output is saying something wrong with the function body.

Here is the trigger function code, where I expect to see record inserted into history_col after I do some inserts to tpayer collection. But nothing inserted to history_col after the inserts.

exports = function(changeEvent) {

const fullDoc = changeEvent.fullDocument;
const updateDescription = changeEvent.updateDescription;

const mongodb = context.services.get("Cluster20434");
const db = mongodb.db("test");

if (changeEvent.operationType == "insert") {
  db.collection("history_col").insertOne({"operation": changeEvent.operationType, "Full Document": fullDoc})
  .then(result => console.log("Inserted"));
  return result;
}

};

Can you go into the trigger itself and see if a data source is already linked to it? They generally appear at the top of the Link Data Source(s) dropdown menu as shown above.

I did brief testing only but managed to get "Inserted" logged with the following function:

  const fullDoc = changeEvent.fullDocument;
  const updateDescription = changeEvent.updateDescription;

  const mongodb = context.services.get("Cluster0");
  const db = mongodb.db("test");

  if (changeEvent.operationType == "insert") {
  db.collection("history_col").insertOne({"operation": changeEvent.operationType, "Full Document": fullDoc})
  .then(result => console.log("Inserted"));
  }

Note: I removed the return result line and changed "Cluster20434" to "Cluster0" to match my test environment

I think if you’re running it with the “Run” button as you say, no documents are being inserted so the trigger is running with no document to work against. I tested by inserting 2 documents (with the Operation Type set to "insert" for this trigger) and it recorded the following the trigger logs:

Note: I inserted a total of 2 times, 1 document each time.

This is the contents of the "test.history_col" namespace after the 2 inserts:

test> db.history_col.find()
[
  {
    _id: ObjectId("6407e5a2e4f987c6ca2b010d"),
    operation: 'insert',
    'Full Document': { _id: ObjectId("6407e5a0f3015b4b893b868a"), a: 1 }
  },
  {
    _id: ObjectId("6407e5a3e4f987c6ca2b02a5"),
    operation: 'insert',
    'Full Document': {
      _id: ObjectId("6407e5a2f3015b4b893b868b"),
      a: 'this is a test string for inserting a document'
    }
  }
]

Jason,
Thank you so much! I removed “return result;” this time and saved the trigger. Then inserted records into the collection and found a row gets inserted into history_col.

So the linked data source is actually already linked since it appears on the top already not at the link button line. Wondering why “return result;” would cause trigger not working as expected?

1 Like

At the level where you have return result; I’m pretty sure result is an undefined variable. (I know JS only extremely vaguely).

It looks like you are using result as a parameter name inside the then which makes it receive the value onFulfilled but only inside the scope of .then(...) and doesn’t push a declaration up to a higher level.

1 Like

Thanks Andy! I’m not familiar with JS either :slight_smile:

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.