使用boto3返回dynamodb中具有最大排序键的所有哈希键项

时间:2019-12-20 13:57:10

标签: python-3.x amazon-dynamodb boto3 dynamodb-queries

给定一个dynamodb表和一个hash-keysort-key,如何使用boto3查询排序键是最大值的所有哈希键项特定的哈希键?

例如,如果表是

HK     SK     Value

A      1      'foo'
       2      'bar'

B      1      'boo'
       2      'far'
       3      'faz'

C      1      'baz'

要检索的boto3查询是什么

A      2      'bar'
B      3      'faz'
C      1      'baz'

a similar question不适用,因为“最后”操作是针对特定的哈希键的,而此查询是针对所有哈希键的。

预先感谢您的考虑和答复。

2 个答案:

答案 0 :(得分:2)

这可能不是您要寻找的答案,但是 DynamoDB没有支持此功能所需的复杂查询功能。您尝试做的事情更适合关系型数据库;与大多数DynamoDB不同,DynamoDB仅在单个文档上运行,并且不维护查询状态。

当您不知道键时,只有两种操作支持搜索记录:

  • 查询需要分区键,并且仅搜索该分区键下的文档。如您所发现的问题所示,它适用于为单个分区键找到具有最大排序键的记录,但是一次不能应用于多个分区键。

  • 扫描搜索整个表,但只能将过滤器应用于每个单独的记录。它没有分组的概念,也不维护任何状态,因此无法跟踪遇到的每个分区键的最高排序键值。

您会看到这些操作都不完全适合您想要执行的操作:您希望像扫描一样搜索整个表,但希望将分区键下的每个记录集视为一个组,例如查询。

最重要的是,这些操作是分页的,并且每次调用仅搜索有限的一组数据。很有可能单个扫描操作将在具有相同分区键的一组记录中间中断。即使DynamoDB确实支持有状态查询,也可能会得出错误的结果,因为它没有查看该分区键下的整个记录​​集。

代码解决方案

由于只能通过使用自己的代码执行查询来实现此目的,所以最简单的解决方案是仅扫描整个表,并使用每个分区键分组的最高排序键来跟踪文档。对于大型数据集,这可能会非常缓慢且昂贵。

如果您担心表的大小,可以进行创新,并使用第二个表通过事务写入为每个分区键存储最高的排序键。对于大数据集,这仍然有些昂贵,但不如扫描整个表那样昂贵。

如果打算将其用作某种版本控制系统,而您通常通常只是想要获取文档的最新版本,则可能需要考虑配置表流,删除排序键并仅覆盖整个文档。当您覆盖文档时,旧文档将被写入流中。您可以创建一个非常基本的lambda,该Lambda将从流中读取并将每个旧文档写入存档表,并使用版本作为排序键。

答案 1 :(得分:1)

没有办法通过使用单个查询来实现这一点,您可以做的是为每个哈希键设置一个特殊的行,如下所示:

      GSI
HK     SK          Value
A  "special_row"   2
A      1          'foo'
A      2          'bar'
B  "special_row"   3
B      1          'boo'
B      2          'far'
B      3          'faz'
C  "special_row"   1
C      1          'baz'

那些特殊的行存储您为给定哈希键而看到的最大排序键。因此,每当需要插入新行时,都需要将其与现有的特殊行进行比较,以查看是否也需要更新该行。 之后,您可以在排序键上构建全局二级索引,并执行如下查询: select * where SK = "special_row"。然后,它应该立即返回具有最大排序键的所有唯一哈希键。