2

我在下面有以下架构,需要进行下面详述的更新。不知道该怎么做。

UserPromo = new Schema
  sendFBInvite:
    earnedIntros:
      type: Number
      default: 0
    earningActionCounter:
      type: Number
      default: 0
    actions:
      type: Number
      default:1
  earnings:
    earnedIntros:
      type: Number
      default: 0
    usedIntros:
      type: Number
      default: 0

每次 sendFBInvite.earningActionCounter 变为 5 我希望 sendFBInvite.earnedIntros 递增,income.earnedIntros 递增 1。同时我想将 sendFBInvite.earningActionCounter 重置为 0

有没有办法在一个电话中做到这一点?在此先感谢您的帮助!

4

2 回答 2

1

不。MongoDB的核心是把所有的业务逻辑都放在应用层,而不是DB。所以简而言之,我认为这是不可能的。

旁注:MongoDB 非常快,您可以运行多个选择/查找查询,然后触发和更新。此外,还有 findAndModify 命令(http://docs.mongodb.org/manual/reference/command/findAndModify/)可能对您有好处。

于 2013-10-09T00:46:38.697 回答
0

这是旧的,但对于其他人来说......前面提到的答案需要在应用程序层中执行此操作,这是正确的。这是一个伪代码示例,说明如何安全有效地执行此类更新:

incrementActionCounter() {
    do {
        var tryagain = false
        // do the common action first, but only if it would not reach
        //  the boundary condition (5)
        err = collection("").update(
            {"sendFBInvite.earnedActionCounter": {$ne: 4}}, 
            {$inc:{"sendFBInvite.earnedActionCounter": 1}}
        )
        // 'not found' means that it's likely already at 4... so...
        if err == "not found" {
            // still need a condition here, in case someone else updated
            //  the value behind our back
            err = collection("").update({"sendFBInvite.earnedActionCounter": 4}, { 
                $inc: { 
                    "sendFBInvite.earnedIntros":1, 
                    "earnings.earnedIntros":1
                }, 
                $set:{
                    "sendFBInvite.earnedActionCounter": 0
                }
            })
            // 'not found' here means something changed between our 2 queries
            if err == "not found" {
                tryagain = true;
            } else if isSomeOtherError(err) {
                return err
            }
        }
    } while(tryagain)
}

显然,根据您的需要,您可以限制重试并在序列失败时返回错误,但类似上述的方法应该可以解决问题而不会产生新的边缘情况。

于 2017-07-25T18:32:07.890 回答