给定一个dynamodb
表和一个hash-key
和sort-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不适用,因为“最后”操作是针对特定的哈希键的,而此查询是针对所有哈希键的。
预先感谢您的考虑和答复。
答案 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"
。然后,它应该立即返回具有最大排序键的所有唯一哈希键。