从 Objectify 实体获取随机条目

发布于 2024-12-12 14:50:45 字数 157 浏览 3 评论 0原文

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

How can I get a random element out of a Google App Engine datastore using Objectify? Should I fetch all of an entity's keys and choose randomly from them or is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

习惯成性 2024-12-19 14:50:45

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

Assign a random number between 0 and 1 to each entity when you store it. To fetch a random record, generate another random number between 0 and 1, and query for the smallest entity with a random value greater than that.

居里长安 2024-12-19 14:50:45

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

  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 ..计数]
  3. ofy.query(X.class).order("- 日期").limit(rnd); //例如 -date 或某些长期索引字段
  4. Last id 是您的...
    (平均你会读取 50% 或至少第一次读取平均减少 50%)

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

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

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

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

You don't need to fetch all.
For example:

  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 = Generate random number [0..countall]
  3. ofy.query(X.class).order("- date").limit(rnd); //for example -date or some chronic indexed field
  4. Last id is your...
    (in average you fatch 50% or at lest first read is in average 50% less)

Improvements (to have smaller key table in cache)!

After first read remember every X elements.
Cache id-s and their position. So next time query condition from selected id further (max ".limit(rnd%X)" will be X-1).

Random is just random, if it doesn't need to be close to 100% fair, speculate chronic field value (for example if you have 1000 records in 10 days, for random 501 select second element greater than fifth day).

Other options, if you have chronic field date (or similar), fetch elements older than random date and younger then random date + 1 (you need to know first date and last date). Second select random between fetched records. If query is empty select greater than etc...

旧夏天 2024-12-19 14:50:45

引自这篇文章关于随机选择一些内容来自对象化数据存储的元素:

如果您的 id 是连续的,一种方法是随机选择 5
已知正在使用的 id 范围内的数字。然后使用带有
“在”过滤器()中。

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

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

-- 乔什

Quoted from this post about selecting some random elements from an Objectified datastore:

If your ids are sequential, one way would be to randomly select 5
numbers from the id range known to be in use. Then use a query with an
"in" filter().

If you don't mind the 5 entries being adjacent, you can use count(),
limit(), and offset() to randomly find a block of 5 entries.

Otherwise, you'll probably need to use limit() and offset() to
randomly select one entry out at a time.

-- Josh

云朵有点甜 2024-12-19 14:50:45

我几乎采用了 Matejc 提供的算法。但是,有三件事:

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

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

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

I pretty much adapt the algorithm provided Matejc. However, 3 things:

  1. Instead of using count() or the datastore service factory (DatastoreServiceFactory.getDatastoreService()), I have an entity that keep track of the total count of the entities that I am interested in. The reason for this approach is that:
    a. count() could be expensive when you are dealing with a lot of objects
    b. You can't test the datastore service factory locally...testing in prod is just a bad practice.

  2. Generating the random number: ThreadLocalRandom.current().nextLong(1, maxRange)

  3. Instead of using limit(), I use offset, so I don't have to worry about "sorting."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文