微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有一种解决方案可以从 mongoose 中完全相同的快照中读取多个集合?

如何解决有没有一种解决方案可以从 mongoose 中完全相同的快照中读取多个集合?

让我解释一下我的问题,这不太可能,但有可能发生。

我有两个集合,A 和 B。B 是 A 的“孩子” - 所以 A 有一个字段 b_id。我想读A,它的B孩子处于一致状态。我担心的是:

A (in state 0) read
B changed (from state 0 to state 1)
B (in state 1) read

我想要的是:

A (in state 0) read
B changed (from state 0 to state 1)
B (in state 0) read

为了帮助想象,一旦我开始读取“过程”,我希望有一个一致的数据库“快照”,所以即使在读取 A 和读取 A 之间的那几毫秒差异中 B 发生了变化, B,我会以我开始阅读时的状态阅读B。

它很难测试,所以它更像是一个理论问题。我正在做关于填充、聚合的研究,但感觉即使这些方法也是按顺序工作的,所以在上述情况下它有可能会失败,但我不知道。哪种方法(如果存在)可以解决上述问题?

解决方法

简短的回答是否定的。

Mongo 不会保留数据的历史值,并且一旦文档更新,除非您设置延迟辅助,否则无法读取其先前版本。

有交易和快照,但它们针对不同的问题,对您的情况没有帮助。

您可以通过使用 $lookup 聚合在同一查询中查询两个集合,从而最大限度地减少读取 2 个集合之间的时间。它不保证集合 B 中的文档在查询期间不会更改,但会显着减少从 2 个集合中读取的时间,因此读取更新版本的机会将大大减少。

如果它不够好,例如如果您的整个业务都依赖于这种保证,或者如果好人因这种读取不一致而死亡,您将需要在应用程序级别实施它。

我的头顶有两个选项。

使用修改时间戳。确保这些时间戳在任何数据修改时单调更新,例如与$currentDate。在查询时获取第一次查询之前的当前时间戳,并将其添加到两个查询的过滤器中,以便在此之后修改的文档将与过滤器不匹配。您将需要实现查询后验证逻辑来​​检查空响应是因为根本没有这样的文档还是因为它被更新,重新尝试读取等。

第二个选项是依靠 change streams 来保持变更流客户端中文档的“最近状态”——该服务将来自集合 B 的更新文档的历史记录保持一段时间。在此设置中,您无需更改文档结构或查询中的任何内容,而是向此更改流服务发出验证请求,以确认没有更改并且您的读取是一致的。

后者的设置有点复杂,您需要考虑变更流的时间延迟。前者更简单,更可靠,只要all写入数据库正确更新修改时间戳。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。