繁体   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