有没有办法以原子方式更新MongoDB中的两个集合?

And*_*rey 17 concurrency mongodb

我收到了一些消息:

{
    messageid: ObjectId
    userid: ObjectId
    message: string
    isread: true|false
}
Run Code Online (Sandbox Code Playgroud)

以及每个用户的消息计数集合:

{
    userid: ObjectId
    total: int
    unread: int
}
Run Code Online (Sandbox Code Playgroud)

当我从"messages"集合中删除消息时,我还需要减少"counts"集合中的"total",并且有条件地(如果"messages.isread"== false)减少"未读"字段.

为此,我需要首先检索消息,检查其"isread"字段,然后更新计数.在这些操作之间有可能将消息标记为已读取,然后我将错误地减少"未读"计数.

有没有办法根据一次拍摄的其他收藏结果有条件地改变一个集合中的某些东西?

Gat*_* VP 13

这里有很多答案,但我想在这里填写所有空白:

有没有办法以原子方式更新MongoDB中的两个集合?

不是.两个集合的原子更新实际上是一个事务.MongoDB不支持跨集合甚至集合内的事务.

MongoDB提供了几个单个文档的原子修饰符.因此,您可以一次增加几个不同的变量($inc).虽然这里有一些限制,但您不能对单个属性执行两个不同的操作.

有没有办法根据一次拍摄的其他收藏结果有条件地改变一个集合中的某些东西?

这里有一些关于原子更新的文档.但是,您真正需要的是队列和某种形式的两阶段提交,或者您需要触发器.

触发器尚未实现,因此在您的情况下它并不是一个真正的选项.

在这些操作之间有可能将消息标记为已读取,然后我将错误地减少"未读"计数.

此时,您有几种不同的策略可以使这种行为具有一定程度的一致性.坦率地说,根据您的描述,您可能需要调查构建一个更新总计的简单队列.


Jos*_*man 5

您不能同时从两个集合中删除文档。您可以做的是使用 findAndModify() 删除文档,以便在删除之前获得其确切状态。这将解决您的未读计数问题。