如何从Google App Engine Datastore获取随机记录?
我有一个数据存储,里面大约有100万个实体(可以理解为数据记录)。我想从中随机取出10个实体。
我不太确定该怎么做,有人能帮帮我吗?
2 个回答
Jason Hall的回答和这里的回答都还不错,但正如他提到的,它们其实并不是真正的随机。如果比如说随机数都聚在一起,即使做十次查询也不会得到随机的结果。为了让结果真正随机,这里有两个可能的解决方案:
解决方案 1
给每个数据存储对象分配一个索引,记录下最大的索引值,然后每次想要获取随机记录时,随机选择一个索引:
MyObject.objects.filter('index =', random.randrange(0, maxindex+1))
优点: 真正随机。速度快。
缺点: 在添加和删除对象时,你需要正确维护这些索引,这会让这两个操作变得比较慢,时间复杂度是O(N)。
解决方案 2
在创建每个数据存储对象时,给它分配一个随机数。然后,第一次获取随机记录时,查询一个随机数大于另一个随机数的记录,并按随机数排序(比如说 MyObject.order('rand_num').filter('rand_num >=', random.random())
)。然后把这个查询结果保存为一个游标在内存缓存中。之后再获取随机记录时,从内存缓存中加载游标,获取下一个项目。如果第一个之后没有项目,就重新运行查询。
为了防止对象的顺序重复,每次读取数据存储时,给刚读取的实体一个新的随机数,并把它保存回数据存储。
优点: 真正随机。不需要维护复杂的索引。
缺点: 需要跟踪游标。每次获取随机记录时都需要进行一次保存操作。
给每个实体分配一个随机数,并把这个随机数存储在实体里。然后,你可以查询出十条记录,这些记录的随机数要大于(或小于)另一个随机数。
你还需要对随机数这一列进行排序,否则,谷歌应用引擎会随机选择10条记录,但这些记录的选择方式并不随机。如果你想找出随机数大于某个随机数的记录,就要对这一列进行升序排序;如果是小于,就要降序排序。
不过,这样的选择并不是完全随机的,因为随机数相近的实体可能会一起出现。如果你想避免这种情况,可以围绕十个随机数进行十次查询,但这样效率会低一些。