创建 DynamoDB GlobalSecondaryIndex 以仅包含具有特定属性的项目

问题描述

我正在按照单表设计原则创建 DynamoDB 表。

我的基表定义如下(无服务器框架):

DataTable:
  Type: AWS::DynamoDB::Table
  Properties:
    TableName: ${self:provider.environment.DATA_TABLE}
    AttributeDeFinitions:
      - AttributeName: pk
        AttributeType: S
      - AttributeName: sk
        AttributeType: S
    KeySchema:
      - AttributeName: pk
        KeyType: HASH
      - AttributeName: sk
        KeyType: RANGE

当前在表中有 GameGamePlayer 对象,其中 Game 如下所示:

{
    "pk": "GAME#game1","sk": "#Meta#game1","numPlayers": 2,... 
}

一个 GamePlayer 看起来像这样:

{
    "pk": "GAME#game1","sk": "PLAYER#player1","score":10,... 
}
{
    "pk": "GAME#game1","sk": "PLAYER#player2","score":20,... 
}

我想创建一个倒排索引来按玩家搜索游戏,所以我更新了我的表声明以添加一个 GlobalSecondaryIndex:

DataTable:
  Type: AWS::DynamoDB::Table
  Properties:
    TableName: ${self:provider.environment.DATA_TABLE}
    AttributeDeFinitions:
      - AttributeName: pk
        AttributeType: S
      - AttributeName: sk
        AttributeType: S
    KeySchema:
      - AttributeName: pk
        KeyType: HASH
      - AttributeName: sk
        KeyType: RANGE
    GlobalSecondaryIndexes:
      - # for finding games by player
        IndexName: ${self:provider.environment.DATA_TABLE_PLAYER_GAME_INDEX}
        KeySchema:
          - AttributeName: sk
            KeyType: HASH
          - AttributeName: pk
            KeyType: RANGE
        Projection:
          NonKeyAttributes: 
            - score
          ProjectionType: "INCLUDE"

所以基本上 pksk 倒置了,我只想投影键和 score 属性,这就是我感兴趣的全部。

查看创建表后的索引,很明显 Dynamo 包含了ALL 基表中的项目,并在它存在的项目上复制了 score

如果我将 score 设置为 HASHRANGE 键,DynamoDB 将仅在索引中包含具有该属性的项目。

鉴于此表中的所有项目都具有 pksk 属性,因此是否将包含在倒排索引中,是否有办法对第三属性具有相同的行为还有吗?

编辑

如果问题不清楚,我们深表歉意。我会尽量准确一些。

我正在使用 DynamoDB 作为后端开发游戏。我遵循此处概述的 One Table 设计模式:https://www.youtube.com/watch?v=7VQs9L-G8O4

基本上,由于表中可以有许多不同类型的对象,因此分区键和排序键是通用的,在本例中为 pksk

目前,在我的表中,我可以存储 3 种类型的对象:GameGamePlayerUser

GameUser,作为顶级对象遵循这样的模式,其中 pk 是唯一 id,而 sk 只是 #Meta#... 和它们的 id。当 User 加入 Game 时,我创建了一个 GamePlayer,其中 pk 是游戏的 id,而 skPLAYER#...User 的 ID。

这让我可以使用 Game 作为 GamePlayerspk 的 id 在一个查询搜索 Game 和所有关联的 sk between #Meta and Player$(请参阅如果不清楚,请观看视频以了解这一点)。

由于表中有很多不同的对象,显然某些属性存在于一个对象上但不存在于其他对象上——例如,属性email只存在于User ,或 score 上的 GamePlayer

视频中提到的模式之一是“倒排”索引的想法。在认情况下,使用 Game 的 id,我可以获得 Game 和所有 GamePlayers。倒排索引是一个 GlobalSecondaryIndex,其中 sk 作为分区键,pk 作为排序键。这意味着,给定 User 的 id,我现在可以找到与该 GamePlayer 关联的所有 User 对象。

为了不复制我的整个数据库,我只想包含 scoreGamePlayer 属性,因此我创建了倒排索引并将 score 设置为 {{1} } 被包括。但是,由于数据库中的每个对象都包含 NonKeyAttributepk 属性,Dynamo 会复制每个对象,并将 sk 属性设置为 {{1} } 对于大多数(因为这些项目上不存在该属性)。

如果我想为 score 创建一个 GlobalSecondaryIndex,例如,使用 undefined 作为分区键或排序键,那么 Dynamo 只会用 Users 对象填充索引(即全局表中可能有 5 个项目,但索引中只有 1 个)。

所以我的问题是,是否可以保留我的倒排索引,但只包括那些具有 email 属性的项目?

示例表:

pk sk 玩家数量 得分 电子邮件
游戏#game1 #Meta#game1 2
游戏#game1 玩家#player1 10
游戏#game1 玩家#player2 20
用户#player1 #Meta#player1 me@email.com

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)