DynamoDB如果属性存在,如何更新地图,否则默默忽略

时间:2017-08-17 08:15:00

标签: amazon-dynamodb

我有一个名为Products的表,其Key是一个范围: orgzviceid + productid 。它有一个名为" 结帐 "的地图属性和数量存储属性名为" prod_stk_qty_i_i "。

首先说,对于产品ID为34的产品,总可用数量为10.一旦购物车结帐,假设结帐ID为5,并且已检查产品ID 34中的2个数量,那么产品& #39; s(适用于productid 34)" 结帐 "地图条目和" prod_stk_qty_i_i "在DynamoDB中将是这样的:

"checkout" : { "5" : 2 }, 
"prod_stk_qty_i_i" : 8 

如果同一产品发生了另一次结账(比如1个数量),如果该结账ID为7,那么结帐可以这样:

"checkout" : { "5" : 2, "7" : 1 }, 
"prod_stk_qty_i_i" : 7 

如果付款,则结帐条目将被删除,数量会增加。

现在,我的要求是在一些超时(30分钟)后定期发布已检出但未发布的产品数量。我这样做是

  • 通过"结帐来增加数量。"'的值
  • 删除结帐。地图条目

即使多次尝试此操作(幂等),此操作也不会失败,因此只有在checkout.checkoutID字段存在时才需要更新。如果没有,它应该简单地忽略。

我尝试了以下内容:

[
  "UpdateItem",
  [
    {
      "TableName": "Products",
      "Key": {
        "orgzviceid": {
          "N": "3000161710"
        },
        "productid": {
          "N": "11"
        }
      },
      "UpdateExpression": "REMOVE #checkout.#checkoutID SET #prod_stk_qty_i_i = #prod_stk_qty_i_i + #checkout.#checkoutID",
      "ExpressionAttributeNames": {
        "#checkout": "checkout",
        "#checkoutID": "235",
        "#prod_stk_qty_i_i": "prod_stk_qty_i_i"
      },
      "ConditionExpression": "attribute_exists(#checkout.#checkoutID)",
      "ReturnValues": "ALL_NEW"
    }
  ]
]

但是,如果没有找到结帐ID 235的结账条目,它会给我一个错误。请注意,我已经写过ConditionExpression只在属性" condition.235"存在。

错误日志:

  

com.amazonaws.dynamodb.v20120810#ConditionalCheckFailedException""消息":"该   条件请求失败..."

那么,我如何编写一个查询,如果映射条目存在,那么执行上述操作,其他方面不会失败? 显然,一个糟糕的黑客是首先检查GetItem查询是否存在提供的CheckoutID的结帐条目,然后只执行此操作,但是,它似乎不正确

2 个答案:

答案 0 :(得分:0)

我相信您错误地使用条件表达式。如果不满足某些标准,条件的要点就是失败。你有什么条件吗?没有条件,它只会执行更新表达式,如果该项不存在,我不希望你得到一个错误。就像查询不存在的项目一样。你应该简单地得到一个空的套装。不是错误。

答案 1 :(得分:0)

您的方法无效,因为您在条件表达式中混合了“Attribute”和“AttributeValue”。让我解释一下:

"ConditionExpression": "attribute_exists(#checkout.#checkoutID)"

在您的表中,checkout是dynamo db中的一个属性,而checkoutID与表模式无关。因此对于dynamo DB,checkoutID是属性值的一部分,而不是属性本身。

因此,拥有你所做的条件是行不通的。 您的用例的条件表达式将表示属性检查存在且值为。但是,为了做到这一点,你需要传递预期的地图,在更新之前将其归结为阅读记录。

我确实认为阅读记录,更新价值并坚持下去应该是在这种情况下继续前进的方式(并不一定是个坏主意) 在这种情况下,请考虑使用某种乐观锁定来防止脏读写。