Mongoose how to listen for collection changes

I have the same demand on an embedded that works quite autonomously, and it is always necessary to auto adjust your operating parameters without having to reboot your system.

For this I created a configuration manager class, and in its constructor I coded a "parameter monitor", which checks the database only the parameters that are flagged for it, of course if a new configuration needs to be monitored, I inform the config -manager in another part of the code to reload such an update.

As you can see the process is very simple, and of course can be improved to avoid overloading the config-manager with many updates and also prevent them from overlapping with a very small interval.

Since there are many settings to be read, I open a cursor for a query as soon as the database is connected and opened. As data streaming sends me new data, I create a proxy for it so that it can be manipulated according to the type and internal details of Config-manager. I then check if the property needs to be monitored, if so, I call an inner-function called watch that I created to handle this, and it queries the subproject of the same name to see what default time it takes to check in the database by updates, and thus registers a timeout for that task, and each check recreates the timeout with the updated time or interrupts the update if watch no longer exists.

 this.connection.once('open', () => {
      let cursor = Config.find({}).cursor();
      cursor.on('data', (doc) => {

        this.config[doc.parametro] = criarProxy(doc.parametro, doc.valor);

        if (doc.watch) {
          console.log(sprintf("Preparando para Monitorar %s", doc.parametro));

          function watch(configManager, doc) {
            console.log("Monitorando parametro: %s", doc.parametro);
            if (doc.watch)  setTimeout(() => {
                Config.findOne({
                  parametro: doc.parametro
                }).then((doc) => {
                  console.dir(doc);
                  if (doc) {
                    if (doc.valor != configManager.config[doc.parametro]) {
                      console.log("Parametro monitorado: %(parametro)s, foi alterado!", doc);
                      configManager.config[doc.parametro] = criarProxy(doc.parametro, doc.valor);
                    } else
                      console.log("Parametro monitorado %{parametro}s, não foi alterado", doc);

                     watch(configManager, doc);
                  } else
                    console.log("Verifique o parametro: %s")
                })

              },
              doc.watch)
          } 
            watch(this, doc);
        }
      });
      cursor.on('close', () => {
        if (process.env.DEBUG_DETAIL > 2) console.log("ConfigManager closed cursor data");
        resolv();
      });
      cursor.on('end', () => {
        if (process.env.DEBUG_DETAIL > 2) console.log("ConfigManager end data");
      });

As you can see the code can improve a lot, if you want to give suggestions for improvements according to your environment or generics please use the gist: https://gist.github.com/carlosdelfino/929d7918e3d3a6172fdd47a59d25b150


To listen for changes to your MongoDB collection, set up a Mongoose Model.watch.

const PersonModel = require('./models/person')

const personEventEmitter = PersonModel.watch()

personEventEmitter.on('change', change => console.log(JSON.stringify(change)))

const person = new PersonModel({name: 'Thabo'})
person.save()

// Triggers console log on change stream
// {_id: '...', operationType: 'insert', ...}

Note: This functionality is only available on a MongoDB Replicaset

See Mongoose Model Docs for more:

If you want to listen for changes to your DB, use Connection.watch.

See Mongoose Connection Docs for more

These functions listen for Change Events from MongoDB Change Streams as of v3.6


I think best solution would be using post update middleware.

You can read more about that here http://mongoosejs.com/docs/middleware.html