2017-07-30 97 views
1

我想弄清楚如何在源数据包含映射值的项目上执行原子更新,并且这些映射的键是动态的。DynamoDB,使用AWS Lambda(NodeJS运行时)映射值的动态原子更新

如果你看看下面的示例数据,我想知道如何在同一个项目上对BSSentDestIp和BSRecvDestIp中的值进行原子更新。我正在阅读文档,但我能找到的唯一东西是list_append,这将给我留下一个附加键/值列表,我将需要遍历和总结。输入数据的

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html

实施例:

{ 
    "RecordId": 31, 
    "UUID": "170ae748-f8cf-4df9-6e08-c0c8a5f029d4", 
    "UserId": "username", 
    "DeviceId": "e0:cb:4e:53:ae:ff", 
    "ExpireTime": 1501445446, 
    "StartTime": 1501441846, 
    "EndTime": 1501441856, 
    "MinuteId": 10, 
    "PacketCount": 1028, 
    "ByteSum": 834111, 
    "BSSent": 98035, 
    "BSRecv": 736076, 
    "BSSentDestIp": { 
    "151.101.129.69": 2518, 
    "192.168.1.254": 4780, 
    "192.168.1.80": 14089, 
    "192.33.31.162": 2386, 
    "54.239.30.232": 21815, 
    "54.239.31.129": 6423, 
    "54.239.31.69": 3255, 
    "54.239.31.83": 18447, 
    "98.138.253.109": 3020 
    }, 
    "BSRecvDestIp": { 
    "151.101.129.69": 42414, 
    "151.101.57.174": 20792, 
    "192.230.66.108": 130175, 
    "192.33.31.162": 56398, 
    "23.194.140.100": 26209, 
    "54.239.26.209": 57210, 
    "54.239.31.129": 188747, 
    "54.239.31.69": 41115, 
    "98.138.253.109": 111775 
    } 
} 
经由LAMBDA执行更新手摇

的NodeJS功能:

function updateItem(UserIdValue, MinuteIdValue) { 

    var UpdateExpressionString = "set PacketCount = PacketCount + :PacketCount, \ 
    ByteSum = ByteSum + :ByteSum, \ 
    BSSent = BSSent + :BSSent, \ 
    BSRecv = BSRecv + :BSRecv"; 

    var params = { 
     TableName: gDynamoTable, 
     Key: { 
      "UserId": UserIdValue, 
      "MinuteId": MinuteIdValue 
     }, 
     UpdateExpression: UpdateExpressionString, 
     ExpressionAttributeValues: { 
      ":PacketCount": gRecordObject.PacketCount, 
      ":ByteSum": gRecordObject.ByteSum, 
      ":BSSent": gRecordObject.BSSent, 
      ":BSRecv": gRecordObject.BSRecv 
     }, 
     ReturnValues: "UPDATED_NEW" 
    }; 

    dynamo.updateItem(params, function(err, data) { 
     if (err) { 
      console.log("updateItem Error: " + err); 
     } else { 
      console.log("updateItem Success: " + JSON.stringify(data)); 
     } 
    }); 
} 

回答

2

更新一个烧毛产品在DynamoDB原子如果读取的物品,并且调用PutItem它保证是原子的。它要么更新所有字段,要么不更新。

现在唯一的问题是我可以看到,你可以有写冲突。假如一个进程读取一个项目,更新一个映射,而另一个进程并行执行相同的操作,则会导致一个PutItem覆盖最近的更新,并且可能会丢失数据。

要解决此问题,您可以使用conditional updates。简而言之,它只允许您在满足指定条件的情况下更新项目。你可以做的是保持每个项目的版本号。当你更新一个项目时,你可以递增一个版本属性,当你写一个项目时,检查你所期望的版本号。否则,您需要再次阅读该项目(有人在您使用它时更新了它)再次执行更新并尝试再次写入。