【发布时间】:2011-12-18 22:51:28
【问题描述】:
如何使用Objectify 从 Google App Engine 数据存储中获取随机元素?我应该获取实体的所有密钥并从中随机选择,还是有更好的方法?
【问题讨论】:
标签: google-app-engine objectify
如何使用Objectify 从 Google App Engine 数据存储中获取随机元素?我应该获取实体的所有密钥并从中随机选择,还是有更好的方法?
【问题讨论】:
标签: google-app-engine objectify
在存储每个实体时为其分配一个介于 0 和 1 之间的随机数。要获取随机记录,请生成另一个介于 0 和 1 之间的随机数,并查询具有大于该随机值的最小实体。
【讨论】:
您不需要全部获取。 例如:
改进(缓存中的键表更小)!
在第一次阅读后记住每个 X 元素。 缓存 id-s 及其位置。因此,下次从所选 id 进一步查询条件(最大“.limit(rnd%X)”将为 X-1)。
随机只是随机,如果不需要接近 100% 公平,则推测慢性字段值(例如,如果您在 10 天内有 1000 条记录,对于随机 501 选择大于第五天的第二个元素)。
其他选项,如果您有长期字段日期(或类似日期),则获取早于随机日期且较早于随机日期 + 1 的元素(您需要知道第一个日期和最后一个日期)。第二次在获取的记录之间随机选择。如果查询为空,则选择大于等...
【讨论】:
引自 this post 关于从 Objectified 数据存储中选择一些随机元素:
如果您的 ID 是连续的,一种方法是随机选择 5 个 已知正在使用的 id 范围内的数字。然后使用一个查询 “在”过滤器()。
如果你不介意这 5 个条目是相邻的,你可以使用 count(), limit() 和 offset() 随机查找包含 5 个条目的块。
否则,您可能需要使用 limit() 和 offset() 来 一次随机选择一个条目。
-- 乔什
【讨论】:
我非常适应 Matejc 提供的算法。但是,有 3 件事:
我有一个实体来跟踪我感兴趣的实体的总数,而不是使用 count() 或数据存储服务工厂 (DatastoreServiceFactory.getDatastoreService())。这种方法的原因就是它: 一种。当您处理大量对象时,count() 可能会很昂贵 湾。您无法在本地测试数据存储服务工厂...在 prod 中测试只是一种不好的做法。
生成随机数:ThreadLocalRandom.current().nextLong(1, maxRange)
我不使用limit(),而是使用offset,所以不用担心“排序”。
【讨论】: