【问题标题】:conditional update in mongodbMongoDB中的条件更新
【发布时间】:2013-10-16 03:09:33
【问题描述】:

我有以下架构,需要进行更新,详情如下。不知道该怎么做。

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

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

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

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

    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)
    }
    

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 你说得对,我尝试了一些不同的方法。我试图避免用户登录到两台机器并执行相同操作导致相同收入的情况。在那种情况下,我可能会遇到收入被正确衡量的情况。话虽这么说,用例不是我现在需要担心的事情。感谢您的回答!
      猜你喜欢
      • 2016-11-15
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多