我是MongoDB的新手,最难理解的是如何确保数据的完整性。
我有两个收藏帖子 - >评论(一对多)。
有没有办法为每个帖子存储评论数量,而不使用two phase commit?
Post {
_id,
text,
commentsNumber
}
Comment {
_id,
text,
postId
}
添加/删除评论时,commentsNumber
必须递增/递减。这是对两个不同集合的两个请求。例如在MongoDB中,写操作在单个文档的级别上是原子的,有可能添加/删除注释,但是commentsNumber不会被更新或反之亦然。
保证诚信的技巧是什么?
commentsNumber
?commentsNumber
?答案 0 :(得分:2)
我怀疑除了上面提到的两阶段提交之外,还有什么能够保证数据完整性。至少到announced v4。
几乎没有什么可以减少错误计数的可能性。 将插入和更新合并为一个bulk。它将减少其中一个操作在应用程序端失败的可能性,因为它是单个请求。
然后检查nInserted === 1
和nModified === 1
。否则,请为给定的帖子ID重新尝试或排队重新计算作业。
对于重试,必须启用retryable writes,因为您将在帖子上使用$inc
,这与幂等操作相距甚远。
另一种选择是应用transactionless方法 - 一种“每个时间段运行脚本以更新commentsNumber”和“根本不存储commentsNumber”的组合。您需要保留上次重新计算作业的时间戳,并计算自该日期以来的新注释。
答案 1 :(得分:1)
由于您提到在帖子中嵌入评论不是您的用例的可行选项,并且不想进行2阶段提交,
我可以考虑以下选项:
在Comment集合的postId属性上创建二级索引。最后在Comment集合上使用基于postId的count(...)函数。
另一个选项是让map-reduce作业在每次添加评论文档时将commentCount和postId存储在新集合中。
在这两个选项中,您不需要在Post文档中存储commentNumbers。需要注意的一点是,由于commentsCount不是Post文档的一部分,这将导致mongo的新查询读取计数。