【问题标题】:Top 10 scores for game leaderboard dynamoDB nodejs sdk query游戏排行榜前 10 名得分 dynamoDB nodejs sdk 查询
【发布时间】: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
}

【问题讨论】:

    标签: node.js amazon-web-services amazon-dynamodb leaderboard


    【解决方案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 查询,以获取每个分区中由于分区键分片而获得的前几名得分者,然后您将使用代码进行排序。

      【讨论】:

        猜你喜欢
        • 2018-06-23
        • 1970-01-01
        • 1970-01-01
        • 2016-10-21
        • 1970-01-01
        • 2012-04-04
        • 1970-01-01
        • 2016-02-10
        • 1970-01-01
        相关资源
        最近更新 更多