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

DynamoDb: How to retrieve the first item (by sort key) for each of a given list of partition keys

我有一个 dynamodb table 存储了我服务器上 运行 进程的历史 运行 数据,我需要一个可以聚合这些进程并查看数据的地方最新的每一个。每个进程都有自己的 ProcessId,这是 dynamodb table 的分区键。排序键是 StartDateTime

{
  ProcessId, // Partition Key
  StartDateTime, // Sort Key
  ... // More data
}

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

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

代替 运行 昂贵的查询或扫描,尝试在 table 上启用 DynamoDB Streams,并使用另一个 lambda 'upsert' 另一个 DynamoDB 中的开始时间 table 以 processId 作为分区键。

然后你可以运行查询这个新 table 上的 processId 的最晚开始时间。

总结一下我从你的 post 中了解到的内容,你的 table 中可能有这样的数据:

PK (id)         SK (timestamp)    Other data
process1        1                 ...
process2        4                 ...
process1        8                 ...
process3        18                ...
process2        25                ...

您的需求是轻松检索:

process1        8                 ...
process2        25                ...
process3        18                ...

正如 sandboxbohemian 所说,我建议您在每次新输入到达时使用流来触发 lambda 函数。但是,我会使用相同的 table 并插入一个具有相同 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       

然后你必须创建一个 PK 等于 "latest" 和 SK 等于 "timestamp" 和项目 "id" 和 "data" 属性的 GSI。这将是一个稀疏索引,意味着只有填充了最新属性的项目才会出现。下面是内容:

latest (GSI PK) timestamp2 (GSI SK)   id        timestamp   Data
true            8                     process1  0           ...
true            25                    process2  0           ...    
true            18                    process3  0           ...   

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

我同意这种模式不直观,但 dynamodb 经常如此