Amazon web services 如何在DynamoDB中有条件地执行SET操作
我在DynamoDb中有一个聚合表,其中包含以下列:Amazon web services 如何在DynamoDB中有条件地执行SET操作,amazon-web-services,amazon-dynamodb,Amazon Web Services,Amazon Dynamodb,我在DynamoDb中有一个聚合表,其中包含以下列:id、sum、count、max、min和hash。我总是想更新sum和count,但只有当我的值大于/小于数据库中已有的值时,我才想更新min和max。此外,我只希望在存储的散列与我发送的内容不同时,此操作才能成功,以防止重新处理相同的数据 我目前有: UpdateExpression:添加总和:总和添加计数:计数集哈希:哈希 UpdateCondition:属性\u不存在(哈希)或哈希:哈希 问题是,对于min和max,我需要这样的东西:
id
、sum
、count
、max
、min
和hash
。我总是想更新sum
和count
,但只有当我的值大于/小于数据库中已有的值时,我才想更新min
和max
。此外,我只希望在存储的散列与我发送的内容不同时,此操作才能成功,以防止重新处理相同的数据
我目前有:
UpdateExpression:添加总和:总和添加计数:计数集哈希:哈希
UpdateCondition:属性\u不存在(哈希)或哈希:哈希
问题是,对于min
和max
,我需要这样的东西:
设置min:min如果:min
和max的类似值。当然,这目前不起作用。我找不到合适的更新函数来在DynamoDb中执行此比较。实现这一目标的正确方法是什么
注:已经有人建议我对dynamodb执行多个请求,并将最大/最小值设置为UpdateCondition
s,但出于数据一致性的原因,我希望避免使用这些多个请求方法
PS2:另一种用JavaScript-sh表达我想要的东西的方式是SET:min
由于UpdateExpression不支持像max()
和min()
这样的函数,因此不可能在一次更新中执行此操作。可以找到支持的操作和功能的文档
实现相同效果的最佳方法是添加一个名为latest
的字段或类似的字段来存储最新的值。您需要将更新表达式更改为如下所示
UpdateExpression:SET hash=:hash,latest=:latest,sum=sum+:latest,count=count+:num
其中,:hash
当然是防止重播的更新哈希,:latest
是最新值,:num
是1或任何增量
然后,您可以使用带有Lambda的DynamoDB流,该Lambda查看每个更新并检查latest
是否小于min
或大于max
。如果没有,则忽略更新,否则执行第二次更新,将min
或max
设置为相应的最新值
这种方法的主要缺点是会有一个小窗口,其中最新的可能超出min
或max
的范围。但是,当您读取记录时,这可以在应用程序代码中轻松地规范化
您还应该考虑从DydioDB流和lambda调用产生的附加成本
< p>在Update中不可能这样做,因为Update表达式不支持诸如“代码>最大())/代码>和<代码> min()/<代码>。可以找到支持的操作和功能的文档
实现相同效果的最佳方法是添加一个名为latest
的字段或类似的字段来存储最新的值。您需要将更新表达式更改为如下所示
UpdateExpression:SET hash=:hash,latest=:latest,sum=sum+:latest,count=count+:num
其中,:hash
当然是防止重播的更新哈希,:latest
是最新值,:num
是1或任何增量
然后,您可以使用带有Lambda的DynamoDB流,该Lambda查看每个更新并检查latest
是否小于min
或大于max
。如果没有,则忽略更新,否则执行第二次更新,将min
或max
设置为相应的最新值
这种方法的主要缺点是会有一个小窗口,其中最新的可能超出min
或max
的范围。但是,当您读取记录时,这可以在应用程序代码中轻松地规范化
你还应该考虑从DydioDB流和lambda调用产生的额外成本
< p>我意识到我想要的是不可能的,所以我找到了解决这个问题的办法。整个更新必须只有一个条件,因为没有设置min=minimum(:min,min)
这样的条件,我不得不接受我的命运,并向DynamoDB发出多个UpdateItem
请求
好在这些更新的执行顺序并不重要。这里的难点是确保每个更新只执行一次。由于我们触发了大量请求(并最终达到峰值),因此很有可能由于通过PutteExceedexception提供的或AWS的一些速率限制而导致更新失败
这是我的最终解决方案
Lambda函数接收具有数百个数据点的有效负载李>
Lambda函数聚合内存中的这些数据点,并生成一个形式为{id,sum,count,min,max}
的中间聚合对象
Lambda函数为每个聚合对象生成3个更新对象,形式如下(这些更新引用相同的记录):
{UpdateExpression:'ADD#SUM:SUM,#COUNT:COUNT'}
{ConditionExpression:'#MAX<:MAX或属性_不存在(#MAX)”,UpdateExpression:'SET#MAX=:MAX'}
{ConditionExpression:'#MIN>:MIN或属性_不存在(#MIN)”,UpdateExpression:'SET#MIN=:MIN'
因为我们需要100%确保这些更新总是成功处理的,所以lambda函数会发送它们