return 使用 boto3 的 dynamodb 中具有最大排序键的所有哈希键项
return all hash-key items with maximum sort-key in dynamodb using boto3
给定 dynamodb
table 和 hash-key
和 sort-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 所有具有最大排序键的唯一哈希键。
给定 dynamodb
table 和 hash-key
和 sort-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'
提前感谢您的考虑和回复。
这可能不是您正在寻找的答案,但 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 所有具有最大排序键的唯一哈希键。