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

return all hash-key items with maximum sort-key in dynamodb using boto3

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

例如,如果 table 是

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'

不适用于我的情况,因为 "last" 操作是针对特定哈希键的,而此查询是针对所有哈希键的。

提前感谢您的考虑和回复。

这可能不是您正在寻找的答案,但 DynamoDB 没有支持此问题所需的复杂查询功能。您正在尝试做什么关系型数据库比较suitable;与其中大多数不同,DynamoDB 仅对单个文档进行操作,不维护查询状态。

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

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

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

您可以看到,这些操作都不是完全适合table您想要做的事情:您想要搜索整个 table,就像扫描一样,但想要处理每个集合分区键下的记录作为一个组,如查询。

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

代码解决方案

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

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

昂贵

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

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

      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"。那么它现在应该 return 所有具有最大排序键的唯一哈希键。