簡體   English   中英

相當於在 DynamoDB 中插入或更新以進行計數

[英]Equivalent of insert or update in DynamoDB for counting

我正在嘗試跟蹤來自 IP 地址的命中。

通常,在 SQL 數據庫中,您可以執行以下操作:

CREATE TABLE website_hits 
(
    ip VARCHAR(45) PRIMARY KEY, 
    hits INTEGER NOT NULL
);

INSERT INTO website_hits 
VALUES ("1.2.3.4", 1) 
ON DUPLICATE KEY UPDATE hits = hits + 1;

DynamoDB 提供了執行原子更新的功能,其中更新表達式作為UpdateItem請求的一部分提供,這意味着它不能用於創建類似於上面顯示的INSERT查詢的條目:

$ aws dynamodb update-item --table-name WebsiteHits --key '{"ip":{"S":"1.2.3.4"}}' --update-expression 'SET hits = hits + :incr' --expression-attribute-values '{":incr":{"N":"1"}}' --return-values UPDATED_NEW
An error occurred (ValidationException) when calling the UpdateItem operation: The provided expression refers to an attribute that does not exist in the item

顯然缺少此功能將使我不得不先執行 GetItem 后跟 UpdateItem,如果有多個進程同時嘗試寫入數據庫,這將導致將不正確的值寫回數據庫。

我 go 如何實現類似於上面顯示的ON DUPLICATE KEY UPDATE語句的插入或更新?

您看到此異常的原因是您的項目當前不存在hits屬性,從而導致異常:

提供的表達式引用了項中不存在的屬性


1. 使用ADD而不是SET

這是推薦的方法。 如果該值不存在,它會自動將其設置為 0,然后添加您提供的值。 您唯一會使用選項 #2 的情況是當屬性存儲在嵌套值中時, ADD對此不起作用。

在更新表達式中使用 ADD 操作將新屬性及其值添加到項目中。 文檔

  • ADD path value

python

table.update_item(
    Key={'ip': '1.2.3.4'},
    UpdateExpression="ADD #hits :incr",
    ExpressionAttributeNames={'#hits': 'hits'},
    ExpressionAttributeValues={':incr': 1}
)

bash

$ aws dynamodb update-item \
--table-name WebsiteHits \ 
--key '{"ip":{"S":"1.2.3.4"}}' \
--update-expression 'ADD #hits :incr' \
--expression-attribute-values '{":incr":{"N":"1"}}' \
--return-values UPDATED_NEW

2.使用if_not_exists Function

如果項目不包含指定路徑的屬性,則 if_not_exists 的計算結果為 value; 否則,它計算為路徑。

這種方法要求您設置一個值,如果該屬性不應存在,則該值最初設置為: :empty=0 與建議您在 DynamoDB 中添加值的方式相比,這更像是一種解決方法。

  • if_not_exists (path, value)

python

table.update_item(
    Key={'voter': 'default_voter'},
    UpdateExpression="set #hits = if_not_exists(#hits, :empty) + :incr",
    ExpressionAttributeNames={'#hits': 'hits'},
    ExpressionAttributeValues={':incr': 1, ':empty': 0}
)

bash

$ aws dynamodb update-item \
--table-name WebsiteHits \ 
--key '{"ip":{"S":"1.2.3.4"}}' \
--update-expression 'set #hits = if_not_exists(#hits, :empty) + :incr' \
--expression-attribute-values '{":incr":{"N":"1"}}' \
--return-values UPDATED_NEW

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM