Amazon web services 如何在DynamoDB中有条件地执行SET操作

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,我需要这样的东西:

我在DynamoDb中有一个聚合表,其中包含以下列:
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函数会发送它们