【问题标题】:How to retrieve a row's position within a DynamoDB global secondary index and the total?如何在 DynamoDB 全局二级索引和总数中检索行的位置?
【发布时间】:2015-05-14 02:06:27
【问题描述】:

我正在实施一个由DynamoDB 和他们的Global Secondary Index 支持的排行榜,如他们的开发人员指南http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html 中所述

但是,对于排行榜系统来说非常必要的两件事是您在其中的位置,以及排行榜中的总数,因此您可以显示 2000 年的第 1 名或类似情况。

使用索引,行以正确的方式排序,我认为这些调用足够便宜,但我还没有找到一种方法,如何通过他们的文档。我真的希望我不必每次都获取整个表来知道一个人在其中的位置,或者整个表的计数(尽管如果它不可用,那可能会被延迟、计算和存储在表)。

我知道DescribeTable 为您提供有关整个表的信息,但我会将过滤器应用于范围键,因此不适合此目的。

【问题讨论】:

  • 这个 Q 已经 3 岁了。答案仍然是“缓慢而艰难”吗?
  • 这个 Q 已经 5 岁了。答案仍然是“缓慢而艰难”吗?

标签: amazon-dynamodb leaderboard


【解决方案1】:

我不知道有任何有效的方法来获得玩家的排名。愚蠢的方法是从最高点的玩家开始查询,向下移动,不断增加计数器,直到到达目标玩家。所以对于最低点的用户,你最终可能会扫描整个范围。

话虽如此,您仍然可以毫无问题地获得前 100 名玩家(Leaders)。只需从最高点的玩家开始查询,并将查询限制设置为100。

此外,对于给定的玩家,您可以在他周围获得 100 名得分相似的玩家。您只需要执行两个查询,例如:

query with hashkey="" and rangekey <= his point, limit 50
query with hashkey="" and rangekey >= his point, limit 50

【讨论】:

  • 哦,我喜欢这个让玩家围绕他的查询,这非常好。但另一方面,是的,我只是不明白为什么它不能作为索引的一部分。有人会假设索引和索引中的数字都可以使用这种东西。 ://
【解决方案2】:

这与我们在开发应用程序时遇到的问题完全相同。以下是我们为解决此问题而提出的两种解决方案:

  1. 使用scanIndex-&gt;false 查询您的索引,这将为您提供限制为 1000 的所有顶级玩家(假设您的分数/点在范围内)。然后应用此数学公式 y = mx+b,您可以进行 2 次迭代,主要是 1最后一个值来找出 m 和 b、x 点和 y 等级。基于此,如果您有用户积分,您将获得排名(这将不是确切的排名值,它是近似值,如果我们在邮件中搜索它显示的某些内容,谷歌也会这样做

    并不是第一次调用时的确切值。

  2. 获取所有记录并将其存储在缓存中,直到下次更新。这是迄今为止我们使用的最好且更便宜的东西。

【讨论】:

    【解决方案3】:

    DynamoDB 的美妙之处在于它针对非常特定(和常见)的用例进行了高度优化。这种优化的代价是许多其他用例无法像使用其他数据库那样容易地实现。不幸的是,你的就是其中之一。话虽如此,使用 DynamoDB 有完全有效的好方法可以做到这一点。我碰巧构建了一个与您的要求相同的应用程序。

    您可以做的是在您的表上启用 DynamoDB 流,并使用 Lambda 函数处理项目更新事件。每次用户的点数发生变化时,您都会重新计算他​​们的排名并更新您的项目。即使您使用相同的扫描操作重新计算排名,这仍然要好得多,因为它将大部分成本从您的读取操作转移到您的写入操作,这首先是 NoSQL 的重点.这种方法还可以使您的积分更新快速并最终保持一致(排名不会立即更新,但可以保证正确更新,除非您的 Lambda 函数出现问题)。

    我建议采用这种方法,一旦达到规模优化,就可以通过在 Redis 之类的东西中按排名缓存用户,除非您有此方面的经验并且可以快速进行设置。首先选择最简单的。如果你担心你的排行榜变化太频繁,你可以通过只重新计算第一名的排名来降低成本,比如 100 个用户,并安排另一个 Lambda 函数每隔几分钟运行一次,扫描所有用户并更新他们的排名同一时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-09
      相关资源
      最近更新 更多