3

如何使用Objectify从 Google App Engine 数据存储中获取随机元素?我应该获取所有实体的密钥并从中随机选择还是有更好的方法?

4

4 回答 4

2

存储时为每个实体分配一个 0 到 1 之间的随机数。要获取随机记录,请生成另一个介于 0 和 1 之间的随机数,并查询具有大于该随机值的最小实体。

于 2011-10-31T23:37:00.083 回答
0

从这篇文章中引用了关于从 Objectified 数据存储中选择一些随机元素的内容:

如果您的 id 是连续的,一种方法是从已知正在使用的 id 范围中随机选择 5 个数字。然后使用带有“in”filter() 的查询。

如果您不介意 5 个条目相邻,则可以使用 count()、limit() 和 offset() 来随机查找包含 5 个条目的块。

否则,您可能需要使用 limit() 和 offset() 一次随机选择一个条目。

——乔什

于 2013-02-06T12:34:59.270 回答
0

您不需要全部获取。例如:

  1. countall = query(X.class).count() // http://groups.google.com/group/objectify-appengine/browse_frm/thread/3678cf34bb15d34d/82298e615691d6c5?lnk=gst&q=count#82298e615691d6c5
  2. rnd = 生成随机数 [0..countall]
  3. ofy.query(X.class).order("-date").limit(rnd); //例如 -date 或一些长期索引字段
  4. 最后一个 id 是你的……(平均而言,你获得 50% 或至少第一次阅读平均少 50%)

改进(在缓存中有更小的键表)!

在第一次阅读后记住每个 X 元素。缓存 id-s 及其位置。因此,下次从所选 id 进一步查询条件(最大“.limit(rnd%X)”将为 X-1)。

随机只是随机,如果不需要接近 100% 公平,则推测慢性字段值(例如,如果您在 10 天内有 1000 条记录,对于随机 501 选择大于第五天的第二个元素)。

其他选项,如果您有长期字段日期(或类似日期),则获取早于随机日期和更早于随机日期 + 1 的元素(您需要知道第一个日期和最后一个日期)。第二次在获取的记录之间随机选择。如果查询为空,则选择大于等...

于 2011-11-12T21:54:38.940 回答
0

我非常适应 Matejc 提供的算法。但是,有 3 件事:

  1. 我没有使用 count() 或数据存储服务工厂 (DatastoreServiceFactory.getDatastoreService()),而是有一个实体来跟踪我感兴趣的实体的总数。这种方法的原因是:当您处理大量对象时,count() 可能会很昂贵 b. 您无法在本地测试数据存储服务工厂...在 prod 中进行测试只是一种不好的做法。

  2. 生成随机数:ThreadLocalRandom.current().nextLong(1, maxRange)

  3. 我没有使用limit(),而是使用offset,所以我不必担心“排序”。

于 2017-10-31T13:36:29.713 回答