Random AWS DynamoDB-随机选择记录/项目?

Random AWS DynamoDB-随机选择记录/项目?,random,amazon-web-services,record,amazon-dynamodb,Random,Amazon Web Services,Record,Amazon Dynamodb,你知道如何从DynamoDB表格中随机挑选一个项目/记录吗?我不相信API中对此有任何规定 我想维护一个NumericId | MyOtherKey(“NumericIdTable”)表,然后生成一个介于0和我拥有的记录总数之间的随机数,然后从NumericIdTable中获取该项,但从长远来看它不会起作用 想法/想法欢迎。我想出了一种从DynamoDB表中随机选取项目的方法: 在表中所有可能的RangeKey上生成一个随机RangeKey 查询此RangeKey和RangeKeyConditi

你知道如何从DynamoDB表格中随机挑选一个项目/记录吗?我不相信API中对此有任何规定

我想维护一个NumericId | MyOtherKey(“NumericIdTable”)表,然后生成一个介于0和我拥有的记录总数之间的随机数,然后从NumericIdTable中获取该项,但从长远来看它不会起作用


想法/想法欢迎。

我想出了一种从DynamoDB表中随机选取项目的方法:

  • 在表中所有可能的RangeKey上生成一个随机RangeKey
  • 查询此RangeKey和RangeKeyCondition大于且限制为1的表
  • 例如,如果使用UUID作为RangeKey的标识符,则可以获得如下所示的随机项

    RandomRangeKey = new UUID
    RandomItem = Query( "HashKeyValue": "KeyOfRandomItems",
                        "RangeKeyCondition": { "AttributeValueList":
                                    "RandomRangeKey",
                                    "ComparisonOperator":"GT"}, 
                        "Limit": 1 )
    
    这样,您将获得一个随机项,并且只消耗1个读取容量

    通过生成比表中使用的最小UUID更小的UUID,可能会错过随机变量的第一个查询。这个机会随着表的放大而缩小,您可以使用SmallerThan比较在同一个随机键上轻松发送另一个请求,从而确保随机项的命中率


    如果您的表格设计不允许使用随机化RangeKey,您可以按照您的方法创建一个单独的RandomItem表格,并将ID存储在随机化RangeKey下。可能的表结构是

    *RandomItemTable
       TableName - HashKey
       UUID - Rangekey
       ItemId
    
    请记住,对于这种方法,您需要管理原始表和随机化表之间的冗余 1) 使用descripe table调用获取该表中的N(总行数) 2) 选择一个介于1和N之间的随机数i 3) 扫描。停下来,直到你看到我


    我正在考虑一个更好的方法来做到这一点。当我有一个好的答案时,我将进行更新。

    如果您使用GUID作为表的哈希键,您可以执行以下操作:

    var client=newamazondynamodbclient();
    var lastKeyEvaluated=新字典()
    { 
    {“您的散列密钥”,新属性值(Guid.NewGuid().ToString())}
    };
    var request=new ScanRequest()
    {
    TableName=您的表名,
    ExclusiveStartKey=lastKeyEvaluated,
    极限=1
    };
    var响应=client.Scan(请求);
    

    这将每次为您提供一个随机记录,因为它会生成一个随机GUID作为lastKeyEvaluated。一种简单有效的方法是:

  • 检索表中的所有项。由于DynamoDB限制只能获取1MB的数据,因此在此操作中使用
    ProjectionExpression
    仅检索主分区键
  • 根据以上结果,您将获得项目总数。现在,只需在0和项目计数之间生成一个随机数。让我们把这个随机数叫做,n
  • 从1中的结果中,获取n-th项,它将是该随机项的主要分区键值
  • 使用刚才计算的随机项的主分区键值执行另一个DynamoDB查询,以获得所有必需的列值

  • 感谢这项功能-我将看看如何实现它。我必须承认,我没有想过在UUID上使用GT比较运算符——好主意:)DynamoDB查询需要指定哈希键。如果您想要为特定的散列键获取一个随机行,上面的答案将起作用。如果您想获得“全局”随机项,则它将不起作用:(我不确定这是否是因为它太旧了,但我可以从中摸索出
    RangeKey==SortKey
    HashKey==PartitionKey
    。不幸的是,你不能在`PartitionKey>上使用
    /
    GT
    ,而且需要明确地拥有一个排序键…现在是2019年了。有没有更好的解决方案?因此,将限制设置为1,您将只获得一个项目。但是,如何将ExclusiveStartKey设置为一个尚不存在的随机UUID,从而获得另一个随机行?生成的UUID不必已经存在于表中吗?而且由于其唯一性,这永远不会发生UUID不需要存在于表中。对于给定的键,DynamoDB知道它“应该”在哪里存在,如果存在。当您选择一个随机项时,DynamoDB从该位置开始,移动到下一项,然后返回。这类似于在街道上查找随机房屋:选择房屋编号,转到房屋编号应位于的位置,然后沿街道移动,直到找到实际房屋。此外,您的\u散列\u键的值可以概括d选择2048个随机位,将其视为字符串,并将其作为起点。有关如何在Java中实现这一点,请参阅。我对此表示怀疑,但您确实可以使用随机值作为分区键。如果您有排序键,您还需要提供一个值,否则您会得到一个与架构不匹配的错误:假设没有重新创建任何项反过来,您应该执行后续查询以获取第一个项。如果您没有执行后续查询,并且您有一个仅包含1个项的集合,并且该项恰好具有非常低的UUID,则您的方法可能需要大量的请求,直到返回单个项为止。这方面的问题:1.如果您的数据(即使只有键)是gre呢大于1MB?那么,你不是在整个数据上随机选择,除非你能保证dynamo每次返回的项目都是真正随机的。2.如果你只扫描了1MB的键,那么每次你需要一个随机行时,这是一个巨大的操作。