原子查询所有集合文档+观察进一步的变化
Atomically query for all collection documents + watching for further changes
我们的 Java 应用将其配置保存在 MongoDB 集合中。当应用程序启动时,它会从 MongoDB 读取所有配置并将它们缓存在地图中。我们希望使用更改流 API 也能够监视配置集合的更新。
因此,在应用程序启动时,首先我们要获取所有配置,从现在开始 - 观察任何进一步的变化。
有没有一种简单的方法可以原子地执行以下操作:
- 检索所有配置(文档)的
find()
- 启动一个
watch()
将发送所有进一步的更新
我的意思是原子地 - 不会丢失任何更新(1 到 2 个人可以使用新配置更新集合)。
为了确保我不会丢失任何更新通知,我发现我可以使用 watch().startAtOperationTime(serverTime)
(对于 4.0 或更高版本的 MongoDB),如下所示。
- 使用
Document hostInfoDoc = mongoTemplate.executeCommand(new Document("hostInfo", 1))
等命令查询MongoDB服务器的当前时间
- 查询所有感兴趣的文档:
List<C> configList = mongoTemplate.findAll(clazz);
- 从 hostInfoDoc 中提取服务器时间:
BsonTimestamp serverTime = (BsonTimestamp) hostInfoDoc.get("operationTime");
- 开始使用保存的服务器时间配置的更改流
ChangeStreamIterable<Document> changes = eventCollection.watch().startAtOperationTime(serverTime);
由于 1 在 2 开始之前结束,我们知道 2 返回的文档至少与该服务器时间上的文档相同或更新。在此服务器时间或之后发生的任何更新都将通过更改流发送给我们(我不关心 运行 再次冗余更新,因为我使用地图作为缓存,所以额外 add/remove不会有什么不同,只要最后一个动作到达)。
我想我也可以使用 watch().resumeAfter(_idOfLastAddedDoc)
(没试过)。由于以下情况,我没有使用这种方法:集合为空,并且在获取所有 (none) 个文档之后,在开始 watch()
之前添加第一个文档。在那种情况下,我没有以前的文档 _id
用作简历标记。
更新
我没有使用 "hostInfo" 来获取服务器时间,这在我们的生产中是无法使用的,我最终使用了 "dbStats" 这样的:
Document dbStats= mongoOperations.executeCommand(new Document("dbStats", 1));
BsonTimestamp serverTime = (BsonTimestamp) dbStats.get("operationTime");
我们的 Java 应用将其配置保存在 MongoDB 集合中。当应用程序启动时,它会从 MongoDB 读取所有配置并将它们缓存在地图中。我们希望使用更改流 API 也能够监视配置集合的更新。
因此,在应用程序启动时,首先我们要获取所有配置,从现在开始 - 观察任何进一步的变化。
有没有一种简单的方法可以原子地执行以下操作:
- 检索所有配置(文档)的
find()
- 启动一个
watch()
将发送所有进一步的更新
我的意思是原子地 - 不会丢失任何更新(1 到 2 个人可以使用新配置更新集合)。
为了确保我不会丢失任何更新通知,我发现我可以使用 watch().startAtOperationTime(serverTime)
(对于 4.0 或更高版本的 MongoDB),如下所示。
- 使用
Document hostInfoDoc = mongoTemplate.executeCommand(new Document("hostInfo", 1))
等命令查询MongoDB服务器的当前时间
- 查询所有感兴趣的文档:
List<C> configList = mongoTemplate.findAll(clazz);
- 从 hostInfoDoc 中提取服务器时间:
BsonTimestamp serverTime = (BsonTimestamp) hostInfoDoc.get("operationTime");
- 开始使用保存的服务器时间配置的更改流
ChangeStreamIterable<Document> changes = eventCollection.watch().startAtOperationTime(serverTime);
由于 1 在 2 开始之前结束,我们知道 2 返回的文档至少与该服务器时间上的文档相同或更新。在此服务器时间或之后发生的任何更新都将通过更改流发送给我们(我不关心 运行 再次冗余更新,因为我使用地图作为缓存,所以额外 add/remove不会有什么不同,只要最后一个动作到达)。
我想我也可以使用 watch().resumeAfter(_idOfLastAddedDoc)
(没试过)。由于以下情况,我没有使用这种方法:集合为空,并且在获取所有 (none) 个文档之后,在开始 watch()
之前添加第一个文档。在那种情况下,我没有以前的文档 _id
用作简历标记。
更新
我没有使用 "hostInfo" 来获取服务器时间,这在我们的生产中是无法使用的,我最终使用了 "dbStats" 这样的:
Document dbStats= mongoOperations.executeCommand(new Document("dbStats", 1));
BsonTimestamp serverTime = (BsonTimestamp) dbStats.get("operationTime");