DynamoDb:如何为每个给定的分区键列表检索第一项(按排序键)

Luk*_*uke 5 amazon-web-services amazon-dynamodb aws-sdk aws-sdk-nodejs dynamodb-queries

我有一个 dynamodb 表,用于存储在我的服务器上运行的进程的历史运行数据,我需要一个可以汇总这些进程并查看其中每个进程的最新数据的地方。每个进程都有它自己的ProcessId,它是 dynamodb 表的分区键。排序键是StartDateTime

{
  ProcessId, // Partition Key
  StartDateTime, // Sort Key
  ... // More data
}
Run Code Online (Sandbox Code Playgroud)

本质上,我需要为我提供的每个 ProcessId 检索最新的 StartDateTime。我正在使用带有 aws-sdk 的 nodejs lambda 来检索数据。我已经研究过使用 BatchGetItem,但我的理解是,对于具有分区键和排序键的表,您需要同时提供两者来检索项目。我也研究过使用查询,但我需要为每个分区运行一个单独的查询,这不是理想的。有谁知道我可以在一次调用中发出此请求的方法,而不必为每个分区进行单独调用?

小智 5

总结一下我从您的帖子中了解到的内容,您的表中可能有这样的数据:

PK (id)         SK (timestamp)    Other data
process1        1                 ...
process2        4                 ...
process1        8                 ...
process3        18                ...
process2        25                ...
Run Code Online (Sandbox Code Playgroud)

您需要轻松检索:

process1        8                 ...
process2        25                ...
process3        18                ...
Run Code Online (Sandbox Code Playgroud)

正如sandboxbohemian所说,我建议您在每次新输入到达时触发一个lambda函数的流。但是,我会使用同一个表并更新一个具有相同 ID 和时间戳等于 0 的项目。此外,我添加了一个二进制属性“latest”,始终设置为“True”,并为当前时间戳添加一个数字属性。按时间顺序,条目将是:

PK (id)         SK (timestamp)    Other data      timestamp2(GSI SK)  latest (GSI PK)
process1        1                 ...                      
process1        0                 ...             1                   true
process2        4                 ...                      
process2        0                 ...             4                   true
process1        8                 ...                      
process1        0                 ...             8        
process3        18                ...                      
process3        0                 ...             18                  true       
process2        25                ...                      
process2        0                 ...             25                  true       
Run Code Online (Sandbox Code Playgroud)

然后,您必须创建一个 GSI,其 PK 等于“最新”,SK 等于“时间戳”以及项目“id”和“数据”属性。这将是一个稀疏索引,这意味着只有填写了最新属性的项目才会出现。下面是内容:

latest (GSI PK) timestamp2 (GSI SK)   id        timestamp   Data
true            8                     process1  0           ...
true            25                    process2  0           ...    
true            18                    process3  0           ...   
Run Code Online (Sandbox Code Playgroud)

如您所见,PK 始终具有相同的值。因此,它允许进行查询或扫描。如果您需要所有最后一个过程,您可以进行扫描。如果进程数量真的很高,您可以使用 latest=True 进行查询,并利用有关时间戳 2 的排序功能。

我同意这种模式不直观,但 dynamodb 经常出现这种情况


san*_*ian 1

您似乎正在尝试某种聚合,而 DynamoDB 通常不是最适合聚合,而是更适合 CRUD 样式操作。

不要运行昂贵的查询或扫描,而是尝试DynamoDB Streams在表上启用,并使用另一个 lambda 以 processId 作为分区键在另一个 DynamoDB 表中“插入”开始时间。

然后,您可以在这个新表的 processId 上运行查询以获取最新开始时间。