Python 从Google App Engine数据存储中获取随机记录?

Python 从Google App Engine数据存储中获取随机记录?,python,google-app-engine,google-cloud-datastore,Python,Google App Engine,Google Cloud Datastore,我有一个模型中约1000000个实体的数据存储。我想从中随机抽取10个实体 我不知道该怎么做?有人能帮忙吗?为每个实体分配一个随机数,并将其存储在实体中。然后查询随机数大于(或小于)其他随机数的十条记录 然而,这并不是完全随机的,因为附近有随机数的实体往往会一起出现。如果你想克服这一点,可以根据十个随机数进行十次查询,但效率较低。Jason Hall的答案并不可怕,但正如他所说,它们也不是真正的随机数。例如,如果随机数都分组在一起,那么即使进行十次查询也不会是随机的。为了让事情变得真正随机,这里

我有一个模型中约1000000个实体的数据存储。我想从中随机抽取10个实体


我不知道该怎么做?有人能帮忙吗?

为每个实体分配一个随机数,并将其存储在实体中。然后查询随机数大于(或小于)其他随机数的十条记录


然而,这并不是完全随机的,因为附近有随机数的实体往往会一起出现。如果你想克服这一点,可以根据十个随机数进行十次查询,但效率较低。

Jason Hall的答案并不可怕,但正如他所说,它们也不是真正的随机数。例如,如果随机数都分组在一起,那么即使进行十次查询也不会是随机的。为了让事情变得真正随机,这里有两种可能的解决方案:

解决方案1

为每个数据存储对象分配一个索引,跟踪最大索引,并在每次希望获得随机记录时随机选择一个索引:

MyObject.objects.filter('index=',random.randrange(0,maxindex+1))

优点:完全随机。快

缺点:在添加和删除对象时,必须正确维护索引,这会使这两个操作都成为O(N)操作

解决方案2

创建每个数据存储编号时,为其分配一个随机数。然后,为了第一次获得随机记录,查询随机数大于其他随机数的记录,并按随机数排序(即
MyObject.order('rand_num')。filter('rand_num>=',random.random())
)。然后将该查询另存为memcache中的游标。要在第一次之后获得随机记录,请从memcache加载光标并转到下一项。如果第一个之后没有项目,请再次运行查询

为了防止对象序列重复,在每次读取数据存储时,为刚读取的实体提供一个新的随机数,并将其保存回数据存储

正面:真正随机的。没有复杂的指数需要维护


下侧:需要跟踪光标。每次获得随机记录时,都需要执行put。

完全正确。可能需要提及随机数的范围(0..1是标准值)。在不影响读取时间效率的情况下增加随机性的一种可能性是将任务排队,为获取的实体分配新的随机数,所以,如果你再次击中其中一个,你将不会得到与它相同的邻居。@NickJohnson你能澄清一下标准范围吗?对不起,我不明白你所说的(0..1)是什么意思?另外,对你们两个来说:我担心这个操作会用到我的一个不等式过滤器(因为在一些查询中,我需要它是随机的,但同时在另一个属性上运行一个等式过滤器)。做10个查询有多糟糕,基本上是成本的10倍吗?别忘了选择“大于或小于”也是随机的。否则,顶部或底部的项目将很少匹配。可能重复的“即使进行十次查询,如果(例如)随机数都分组在一起,也不会是随机的”-我猜您指的是分配给数据存储行的随机数。这只是少数记录的一个问题-值之间差距的标准偏差随着值数量的增加而缩小,达到统计上不重要的程度。您的解决方案1需要一个单调计数器,这在App Engine上是一个缓慢而昂贵的操作。解决方案2使用无替换的选择,这与OP所要求的不同。没错,如果没有太多记录,或者如果您以很高的速度检索记录,那么这种简单的方法就会失败。此外,设置rand_num值后,其分布是固定的。你不会得到一个很好的均匀分布,而且会有一些记录很少被选择。不,这是我的观点——你拥有的记录越多,区间的标准偏差越小。也就是说,分配了异常小间隔的实体将按比例减少。Wooble建议一旦你选择了一张唱片,就重新分配号码,这也有助于抵消这一影响。