2017-08-17 2 views
0

Keyという名前のテーブルがあり、キーが範囲です。orgzviceid + productidです。それは「チェックアウト」と「prod_stk_qty_i_i」と呼ばれる属性を格納量と呼ばれるマップの属性を持っています。DynamoDB属性が存在する場合にマップを更新する方法、それ以外の場合は黙って無視する

最初に、製品IDが34の製品の場合、利用可能な総量は10です。カートのチェックアウトが発生すると、Checkout IDが5であると仮定し、製品ID 34を2個確認したら、製品の「チェックアウト」マップエントリとDynamoDBの中にこのようなものになるだろう「はprod_stk_qty_i_i」(商品コード34用):

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

別のチェックアウトは言う(同じ製品のための1つの量を発生した場合)、そのチェックアウトIDが7の場合、 nは、このようなチェックアウトooks:支払いが行われた場合

"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" 
    } 
    ] 
] 

チェックアウトのエントリは、私が唯一の属性場合は、アップデートを行うにはConditionExpressionを書いたレジ番号235注見つかりされていない場合にはしかし、それは私にエラーを与えます「条件235」が存在する。

エラーログ:

com.amazonaws.dynamodb.v20120810#のConditionalCheckFailedException」、 "メッセージ": " 条件付き要求が失敗した..."

をので、私は書くのですかそのマップエントリが存在する場合は上記の操作を行い、それ以外の場合は失敗しないようなクエリ 明らかに、1つの悪いハックは、Checkoutエントリが存在する場合にGetItemクエリを最初にチェックし、しかし、それはちょうど右のように見えません

答えて

0

条件式を間違って使用していると思います。ある条件が満たされない場合、条件付きのポイントは失敗することになります。条件付きのものは何ですか?条件付きでなければ、更新式を実行するだけです。アイテムが存在しない場合は、エラーが発生するとは思われません。存在しない項目を照会するのと同じです。単に空のセットを戻すだけです。エラーではありません。

+0

私の要件が「何かのIF条件を更新する」ことである場合はどうですか? – Ouroboros

+0

条件式のポイントは、演算に条件を課すことです。それは、ユーザーが望む何かを失敗/断定することができます。 – Rahul

0

"Attribute"と "AttributeValue"を条件式で混合しているため、アプローチは機能しません。私に説明してみましょう:checkoutIDがテーブルスキーマに関連しない方法であるのに対し、あなたのテーブルには

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

、チェックアウトは、ダイナモDB内の属性です。したがって、ダイナモDBの場合、checkoutIDは属性自体の値ではなく属性の値の一部です。

したがって、あなたがしていることを条件とすることは動作しません。 あなたのユースケースの条件式は、属性チェックアウトが存在し、その値がであると言うものです。しかし、そうするためには、更新する前にレコードを読むことに至るまで期待される地図を渡す必要があります。

私は、レコードを読み、値を更新し、それを維持することは、この場合に先行する方法であるべきだと思います。(そして必ずしも悪い考えではありません) この場合、汚れた読み書きを防止します。

関連する問題