Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get notification for changed documents in mongodb

i'm trying to use mongodb as a network wide configuration storage. This the same app runs on multiple machines on the network, each pulls its configuration from its local mongodb. The mongodbs are synced. What i would like is to get a callback/notification in all n-1 apps if one application changes any of the config values. Is this kind of setup possible ?

(It would save me from doing the network transfer/syncronisation etc. myself.)

like image 606
joekr Avatar asked Apr 04 '12 15:04

joekr


People also ask

How do I listen for changes in MongoDB?

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

How do I get most recent files in MongoDB?

To get last inserted document, use sort() along with limit(1).

How does MongoDB change stream work?

Change streams allow applications to access real-time data changes without the complexity and risk of tailing the oplog. Applications can use change streams to subscribe to all data changes on a single collection, a database, or an entire deployment, and immediately react to them.


2 Answers

As of mongodb 3.6, you can now hook actions to the change stream. This gives you a tailable cursor which you can use to listen to changes (e.g. crud operations) on a particular collection.

The change stream is built on top of the oplog and is accessible for anything that is using the oplog. Change streams are resumable and also can be used with aggregation operators such as $match, $project...

More info here (Java example): http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/

And here is the snippet from https://www.mongodb.com/mongodb-3.6 (Java):

// 1. The database for reactive, real-time applications
 MongoClient mongoClient;

// Create a new MongoClient with a MongoDB URI string.
if (args.length == 0) {
// Defaults to a localhost replicaset on ports: 27017, 27018, 27019
  mongoClient = new MongoClient(new
  MongoClientURI("mongodb://localhost:27017,localhost:27018,localhost:27019"));
} else {
  mongoClient = new MongoClient(new MongoClientURI(args[0]));
}

// Select the MongoDB database.
MongoDatabase database = mongoClient.getDatabase("testChangeStreams");
database.drop();
sleep();

// Select the collection to query.
MongoCollection<Document> collection = database.getCollection("documents");

// Create the change stream cursor.
MongoCursor<Document> cursor = collection.watch().iterator();

If you are working in C#, examples can be found here:

    var inventory = database.GetCollection<BsonDocument>("inventory");

    var document = new BsonDocument("x", 1);
    inventory.InsertOne(document);
    new Thread(() =>
    {
        Thread.Sleep(TimeSpan.FromMilliseconds(100));
        var filter = new BsonDocument("_id", document["_id"]);
        var update = "{ $set : { x : 2 } }";
        inventory.UpdateOne(filter, update);
    })
    .Start();

    // Start Changestream Example 2
    var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
    var enumerator = inventory.Watch(options).ToEnumerable().GetEnumerator();
    enumerator.MoveNext();
    var next = enumerator.Current;
    enumerator.Dispose();
    // End Changestream Example 2

    var expectedFullDocument = document.Set("x", 2);
    next.FullDocument.Should().Be(expectedFullDocument);
like image 135
Darxtar Avatar answered Sep 23 '22 23:09

Darxtar


MongoDB doesn’t yet have triggers, but you can hook your application to tail off the oplog collection and do something every time a document is deleted (or updated, or inserted, etc.)

The 3 part blog post here might be helpful on how to do this : http://www.kchodorow.com/blog/2010/10/12/replication-internals/

like image 20
Sid Avatar answered Sep 23 '22 23:09

Sid