在MongoDB中获取文档更改的通知

13

我正在尝试将MongoDB作为网络范围的配置存储。同一应用在网络上的多台机器上运行,每个应用程序从其本地的MongoDB中获取其配置。这些MongoDB是已同步的。我想要的是,如果一个应用程序更改了任何配置值,则在所有n-1个应用程序中都会收到回调/通知。

这种设置是否可行?(这将使我不必自己进行网络传输/同步等操作。)

3个回答

12
从mongodb 3.6版本开始,您现在可以将操作挂钩到更改流中。这为您提供了一个可用于监听特定集合上的更改(例如crud操作)的尾随光标。
更改流是建立在oplog之上的,对于使用oplog的任何内容都是可访问的。更改流是可恢复的,也可以与$match、$project等聚合运算符一起使用。
这里有更多信息(Java示例):http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/ 这里是来自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();

如果你正在使用C#开发,可以在这里找到示例:

    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);

8
MongoDB目前还没有触发器,但是您可以将应用程序连接到oplog集合并在每次删除(或更新、插入等)文档时执行某些操作。这里有一个包含3部分的博客文章,对如何实现此功能可能有所帮助: http://www.kchodorow.com/blog/2010/10/12/replication-internals/

1
那个链接现在已经失效了。 - captncraig
2
这已经不是最新的了,应该接受2017年的答案。 - efx

2
你说的mongodbs同步是什么意思?它们是否在彼此之间复制数据?我假设不是,因为听起来你想要管理这个同步。
过去,我使用MongoDB和asp实现了类似的功能,需要一个集中式的mongo实例(副本对等等)。基本上,每当对本地实例进行更改时,中央实例上的封顶集合也会更新为配置值的新版本,并记录该值最后一次更新的时间戳以及更新该值的服务器。
然后,在各个服务器上运行单独的线程,保持对中央实例的可追溯游标开放状态。每当游标检索到新记录时,就会根据本地实例的时间戳比较新值并相应地更新(或不更新)。在比较那些时间戳和“权威”的更改服务器时必须小心,以确保您不会遇到更新风暴。您还需要注意更新是因为某人实际上更改了值还是因为该值被“复制” - 如果更新是复制更新,则不希望更新中央实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接