游戏排行榜前 10 名得分 dynamoDB nodejs sdk 查询

Posted

技术标签:

【中文标题】游戏排行榜前 10 名得分 dynamoDB nodejs sdk 查询【英文标题】:Top 10 scores for game leaderboard dynamoDB nodejs sdk query 【发布时间】:2021-10-22 13:28:12 【问题描述】:

我有一个具有以下字段的 dynamodb -

id (primary key) (string)
name (user name) (string)
score (sort key) (number)
player (type - regular/new etc.) (string)

我只是想从数据库中获得前 10 名。 按照 AWS https://docs.aws.amazon.com/AWSjavascriptSDK/latest/AWS/DynamoDB.html#query-property的文档尝试了几个查询

这是我的查询代码-

const ddb = new AWS.DynamoDB.DocumentClient(apiVersion: '2012-08-10');

function getItems()
  var params = 
  ExpressionAttributeValues: 
   ":v1": 
     S: "regular"
    
  , 
  KeyConditionExpression: "player = :v1", 
  TableName: "cloudtag_result"
 ;
 return ddb.scan(params).promise();

但它给了我以下错误

2021-08-21T08:36:43.092Z    1bbd5490-4248-4f06-94ea-724e6d23dac5    ERROR   ValidationException: Query condition missed key schema element: id
    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) 
  code: 'ValidationException',
  time: 2021-08-21T08:36:43.031Z,
  requestId: 'JH91VON2KGVNP7HF41VCBELTUVVV4KQNSO5AEMVJF66Q9ASUAAJG',
  statusCode: 400,
  retryable: false,
  retryDelay: 47.72972319109784


【问题讨论】:

【参考方案1】:

DynamoDB 有一个基本限制,即您绝对必须在所有查询中指定分区键(或您所称的主键)。它必须与表中的内容完全匹配,不允许“模糊”查询。

您在player = .. 上查询,但您没有指定 id。没有办法让它在发电机中工作,你需要指定主键。

如果您的访问模式要求您能够按玩家名称查找,则您需要将玩家名称放在 PK 或 SK 中,否则您需要在您的应用程序中而不是在 dynamodb 服务器上进行过滤.

您可能想要所谓的“单表设计”。 Rich Houlihan 的这次演讲强烈推荐给任何使用 dynamo 进行数据建模的人 :)

https://www.youtube.com/watch?v=HaEPXoXVf2k

【讨论】:

【参考方案2】:

您可以为此创建一个全球二级索引 (GSI)

player 作为您的GSI 分区键,将score 作为您的GSI 排序键,您实际上可以针对这个GSIquery /strong> 通过提供player 的值并使用scanIndexForward (true/false) 根据GSI 排序键 以升序或降序获取数据。

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html

但是,当您的数据变大时,您可能会在 GSI 上遇到Hot Partition 问题,这是由于 GSI 分区键 过于集中在指定键,例如regular。因此,如果您可以开始进行分区键分片会更好,您可以在player 中添加一个后缀,例如regular#1, regular#2... regular#n。这样就可以避免Hot Partition的问题了。

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-sharding.html

同样,如果您采用此解决方案,您将需要在 GSI 上执行 n times 查询,以获取每个分区中由于分区键分片而获得的前几名得分者,然后您将使用代码进行排序。

【讨论】:

以上是关于游戏排行榜前 10 名得分 dynamoDB nodejs sdk 查询的主要内容,如果未能解决你的问题,请参考以下文章

C语言 猜数字游戏代码

在 Google Play 游戏中更新(递增/递减)排行榜得分

前 10 名最大得分手的 PFQuery [关闭]

2022年4月中国数据库排行榜:华为GaussDB 挺进前四,榜单前八得分扶摇直上

使用谷歌的 Unity3d 插件自定义 UI 的谷歌玩游戏服务排行榜

P30 Pro劲敌!DxO官宣新机:排行榜又要变