首页 > 解决方案 > 原子查询所有集合文档 + 观察进一步的变化

问题描述

我们的 Java 应用程序将其配置保存在 MongoDB 集合中。当应用程序启动时,它会从 MongoDB 中读取所有配置并将它们缓存在 Maps 中。我们希望使用更改流 API 也能够监视配置集合的更新。因此,在应用程序启动时,首先我们要获取所有配置,从现在开始 - 观察任何进一步的变化。有没有一种简单的方法可以原子地
执行以下操作:

  1. Afind()检索所有配置(文档)
  2. 启动一个watch()将发送所有进一步更新的

我的意思是原子地 - 不会错过任何更新(在 1 到 2 之间,有人可以使用新配置更新集合)。

标签: mongodbmongodb-java

解决方案


为了确保我不会丢失更新通知,我发现我可以使用watch().startAtOperationTime(serverTime)(对于 4.0 或更高版本的 MongoDB),如下所示。

  1. 使用以下命令查询 MongoDB 服务器的当前时间Document hostInfoDoc = mongoTemplate.executeCommand(new Document("hostInfo", 1))
  2. 查询所有有趣的文档:List<C> configList = mongoTemplate.findAll(clazz);
  3. 从 hostInfoDoc 中提取服务器时间:BsonTimestamp serverTime = (BsonTimestamp) hostInfoDoc.get("operationTime");
  4. 启动使用保存的服务器时间配置的更改流 ChangeStreamIterable<Document> changes = eventCollection.watch().startAtOperationTime(serverTime);

由于 1 在 2 开始之前结束,我们知道 2 返回的文档至少与该服务器时间上的文档相同或更新。并且在此服务器时间或之后发生的任何更新都将通过更改流发送给我们(我不关心再次运行冗余更新,因为我使用地图作为缓存,所以额外的添加/删除不会有什么不同,只要最后一个动作到达)。

我想我也可以使用watch().resumeAfter(_idOfLastAddedDoc)(没有尝试)。由于以下情况,我没有使用这种方法:集合为空,并且在获取所有(无)文档之后添加第一个文档,并且在启动watch(). 在那种情况下,我没有以前的文档_id可用作简历令牌。

更新

我没有使用“hostInfo”来获取无法在我们的生产中使用的服务器时间,而是像这样结束了使用“dbStats”:

Document dbStats= mongoOperations.executeCommand(new Document("dbStats", 1)); BsonTimestamp serverTime = (BsonTimestamp) dbStats.get("operationTime");


推荐阅读