如何在 DynamoDB 中查询和排序两个单独的排序键?

How to query and order on two separate sort keys in DynamoDB?

GROUPS
    userID: string
    groupID: string
    lastActive: number
    birthday: number

假设我有一个名为 GROUPS 的 DynamoDB table,它存储具有这些属性的项目。 table 记录哪些用户加入了哪些组。用户可以同时在多个组中。因此,复合主键最常见的是:

partition key: userID
sort key: groupID

但是,如果我想查询特定组中的所有用户,在特定生日范围内,按 lastActive 排序,这可能吗?如果可以,我需要什么索引要创建?

我可以合成 lastActiveuserID 来创建合成排序键,如下所示:

GROUPS
    groupID: string
    lastActiveUserID: string (i.e. "20201230T09:45:59-abc123")
    birthday: number

这将创建一个不同的复合主键,其中分区键为 groupID,排序键为 lastActiveUserID,这将根据参与者上次活动的时间对参与者进行排序,然后按生日过滤的二级索引?

正如所写,不,这是不可能的。

within a specific birthday range

意味着sk_birthday between :start and :end

sorted by lastActive

将 lastActive 隐含为排序键。

它们是互斥的...我无法设计能够以可用格式包含这两个值的排序键。

您可以使用散列键 group-idlastActive 作为排序键的全局二级索引,然后按生日进行过滤。但是,这只会影响返回的数据,不会影响读取的数据,也不会影响读取该数据的成本。此外,由于 DDB 一次只能读取 1MB 的数据,如果给定的组可能有超过 1MB 的成员,则必须在循环中重复调用它。

此外,当您的索引具有与 table 不同的分区(散列)键时,这就是全局二级索引 (GSI)。如果您的索引具有与 table 相同的分区键但排序键不同,则可以使用本地二级索引 (LSI)

来完成

但是对于任何给定的查询,您只能使用 table 或给定的索引。不能同时使用多个索引

说了这么多,“特定生日范围” 对您来说到底是什么意思?也许您可以拥有一个 GSI,其中散列键是 "group-id#birthday-period",排序键是 lastActive

例如,“给我下个月的 GROUPA 生日”
查询(hs = "GROUPA#NOVEMBER")

但如果您想要 11 月和 12 月,则必须进行两次查询并自行合并和排序结果。

有效且高效地使用 DDB 意味着避免 Scan() 并避免使用 filterExpressions,您知道这会丢弃大量读取的数据。