Amazon dynamodb 如何检索行';s在DynamoDB全球二级指数中的位置和总数?

Amazon dynamodb 如何检索行';s在DynamoDB全球二级指数中的位置和总数?,amazon-dynamodb,leaderboard,Amazon Dynamodb,Leaderboard,我正在实施一个排行榜,该排行榜由DynamoDB及其全局二级索引支持,如《开发者指南》中所述 但是,对于排行榜系统来说,有两件事是非常必要的,那就是你在排行榜中的位置,以及你在排行榜中的总数,所以你可以显示2000年的第1次,或者类似的情况 使用索引,行被正确地排序,我假设这些调用足够便宜,但是我还没有找到一种方法,到目前为止,如何通过它们的文档来实现。我真的希望我不必每次都获取整个表来知道一个人在其中的位置,或者整个表的计数(尽管如果不可用,可能会延迟、计算并在预定时间存储在表之外) 我知道d

我正在实施一个排行榜,该排行榜由
DynamoDB
及其
全局二级索引
支持,如《开发者指南》中所述

但是,对于排行榜系统来说,有两件事是非常必要的,那就是你在排行榜中的位置,以及你在排行榜中的总数,所以你可以显示2000年的第1次,或者类似的情况

使用索引,行被正确地排序,我假设这些调用足够便宜,但是我还没有找到一种方法,到目前为止,如何通过它们的文档来实现。我真的希望我不必每次都获取整个表来知道一个人在其中的位置,或者整个表的计数(尽管如果不可用,可能会延迟、计算并在预定时间存储在表之外)


我知道
descripbetable
提供了关于整个表的信息,但是我会对范围键应用过滤器,因此这不适合这个目的。

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

尽管如此,你仍然可以毫无问题地获得前100名球员(领头羊)。只需从具有最高点的玩家开始执行查询,并将查询限制设置为100

同样,对于一个给定的球员,你可以让他周围的100名球员获得相似的分数。您只需要执行以下两个查询:

query with hashkey="" and rangekey <= his point, limit 50
query with hashkey="" and rangekey >= his point, limit 50
使用hashkey=”“和rangekey=his点进行查询,限制为50

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

  • scanIndex->false
    查询你的索引,这将给你所有排名靠前的玩家(假设你的分数/积分在范围内)提供1000分的限制。然后应用这个数学公式y=mx+b,在这里你可以进行2次迭代,主要是1次迭代,最后一次迭代求出m和b,x点和y秩。基于此,如果你有用户的分数,你将得到排名(这不是确切的排名值,而是近似值,如果我们在邮件中搜索,谷歌也会这样做)

    并且在第一次调用中没有精确的值

  • 获取所有记录并将其存储在缓存中,直到下一次更新。这是目前为止我们使用的最好且成本更低的东西


  • DynamoDB的优点在于它针对非常特定(和常见)的应用进行了高度优化用例。这种优化的代价是,许多其他用例无法像其他数据库那样轻松实现。不幸的是,您的用例就是其中之一。也就是说,使用DynamoDB有完全有效的好方法来实现这一点。我碰巧构建了一个与您的应用程序具有相同的需求

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


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

    ooh,我喜欢这样的查询,让玩家接近他,这非常好。不过,另一点,是的,我不明白为什么这不能作为索引的一部分。一个uld假设索引和索引中的数字都有类似的功能。/这个Q已经有3年了。答案仍然是“又慢又难”吗?这个Q已经有5年了。答案仍然是“又慢又难”吗?