Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to watch for changes to specific fields in MongoDB change stream

I am using the node driver for mongodb to initiate a change stream on a document that has lots of fields that update continuously (via some logic on the insert/update end that calls $set with only the fields that changed), but I would like to watch only for changes to a specific field. My current attempt at this is below but I just get every update even if the field isn't part of the update.

I think the "updateDescription.updatedFields" is what I am after but the code I have so far just gives me all the updates.

What would the proper $match filter look like to achieve something like this? I thought maybe checking if it's $gte:1 might be a hack to get it to work but I still just get every update. I've tried $inc to see if the field name is in "updatedFields" as well but that didn't seem to work either.

const MongoClient = require('mongodb').MongoClient;

const uri = 'mongodb://localhost:27017/?replicaSet=rs0';
MongoClient.connect(uri, function(err, client) {

    const db = client.db('mydb');
    // Connect using MongoClient
    var filter = {
        $match: {
            "updateDescription.updatedFields.SomeFieldA": { $gte : 1 },
            operationType: 'update'
        }
    };

    var options = { fullDocument: 'updateLookup' };
    db.collection('somecollection').watch(filter, options).on('change', data => {
        console.log(new Date(), data);
    });
});
like image 812
Zack Sloane Avatar asked Apr 03 '18 03:04

Zack Sloane


People also ask

How do I watch changes in MongoDB?

You can watch for changes in MongoDB using the watch() method on the following objects: Collection. Database. MongoClient.

How do I search for a specific field in MongoDB?

You can select a single field in MongoDB using the following syntax: db. yourCollectionName. find({"yourFieldName":yourValue},{"yourSingleFieldName":1,_id:0});

How do MongoDB change streams work?

Change streams transform a MongoDB database into a real-time database by taking advantage of MongoDB's replication process. They monitor replication in MongoDB, providing an API for external applications that require real-time data without the risk involved in tailing the oplog or the overhead that comes with polling.

How do I watch a collection in MongoDB?

To obtain a list of MongoDB collections, we need to use the Mongo shell command show collections . This command will return all collections created within a MongoDB database.


1 Answers

So i figured this out...

For anyone else interested: My "pipeline" (filter, in my example) needs to be an array

this works...

const MongoClient = require('mongodb').MongoClient;

const uri = 'mongodb://localhost:27017/?replicaSet=rs0';
MongoClient.connect(uri, function(err, client) {

    const db = client.db('mydb');
    // Connect using MongoClient
    var filter = [{
        $match: {
            $and: [
                { "updateDescription.updatedFields.SomeFieldA": { $exists: true } },
                { operationType: "update" }]
        }
    }];

    var options = { fullDocument: 'updateLookup' };
    db.collection('somecollection').watch(filter, options).on('change', data => 
    {
        console.log(new Date(), data);
    });
});
like image 154
Zack Sloane Avatar answered Sep 19 '22 01:09

Zack Sloane