我有一系列信息:

{
    messageid: ObjectId
    userid: ObjectId
    message: string
    isread: true|false
}

以及每个用户的邮件计数集合:

{
    userid: ObjectId
    total: int
    unread: int
}

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

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

有没有一种方法可以根据其他集合的结果一次性有条件地更改一个集合中的某些内容?

推荐答案

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

有没有办法对MongoDB中的两个集合进行原子更新?

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

MongoDB在一个文档中提供了several modifiers个原子.所以你可以一次增加几个不同的变量($inc).虽然这里有一些限制,但不能对一个属性执行两个不同的操作.

有没有一种方法可以根据其他集合的结果一次性有条件地更改一个集合中的某些内容?

这里有一些关于atomic updates的文件.然而,您真正需要的是一个队列和某种形式的two-phase commit或触发器.

触发器有not yet been implemented个,所以在你的情况下它不是一个选项.

在这些操作之间,邮件可能会被标记为已读,然后我会错误地减少"未读"计数.

在这一点上,你有两种不同的策略来让它保持一定程度的一致性.坦率地说,根据您的描述,您可能需要研究构建一个简单的队列来更新总数.

Mongodb相关问答推荐

为什么这个查询可以在MongoDB中使用?

减法聚合Mongo文档Golang

MongoDB 聚合 groupBy 日期并计算子文档

Mongodb聚合查找连接两个对象字段的集合数组匹配对象索引字段的总和

在 MongoDB 中,如何使用对当前值进行操作的函数来更新嵌套文档的值?

如何在mongodb中级联删除文档?

通过 _id 更新一个文档(无效的 BSON 字段名称 _id)

MongoDB 更改流副本集限制

从 PHP 打印 MongoDB 日期

更新 mongoengine 中的嵌入文档列表

MongoDB $或PHP中的查询

使用 MongoDB 更新数组字段内的特定键/值

是否有适用于 Linux 的 MongoDB GUI 桌面应用程序?

Mongo按实际上是数字的字符串值排序

mongoose 使用 $cond 中的 $exists 聚合

将新值推送到 mongodb 内部数组 - mongodb/php

带有 either or查询的mongoose findOne

MongoError:failed to connect to server [localhost:27017] on first connect

Spring Data MongoDB - 在哪里以编程方式为 Mongo 集合创建索引?

MongoMapper 和迁移