【问题标题】:Selecting random records from appengine data store (java)从应用引擎数据存储区(java)中选择随机记录
【发布时间】:2014-09-27 16:51:58
【问题描述】:

我正在使用 GAE 和 Java(JPA) 从我的数据库中检索记录。

目前我有超过 2000 条记录(并且还在增长),我必须展示其中的 60 条完全随机的记录。 目前我通过以下方式实现它

  1. 从数组中的数据库中获取所有键
  2. 在 0
  3. 通过键值获取这60条记录

我在这个实现中面临的问题是,因为每次请求都会下载整个 DB ket 集,所以它给“Datastore Small Operations”(免费)qouta 增加了很多,而且如果要扩展此代码,它会感觉效率低下未来。

有什么方法可以在不下载所有密钥的情况下获得随机 60 条记录?

【问题讨论】:

    标签: java google-app-engine jpa google-cloud-datastore


    【解决方案1】:
    1. 您可以对所有 2000 个键进行内存缓存,这样您就不必在每个请求中都查询它们。

    2. 您可以对 60 条随机记录进行内存缓存,这样每个用户都可以获得已经向以前的用户显示过的唯一且随机的结果(可能不适用于您的情况)。

    但这些都不是可扩展的。

    【讨论】:

    • 经过大量研究后,其他人也提出了与您的第 1 点相同的建议。我认为应该阅读更多有关 memcache 的信息,看看它是如何工作的。
    【解决方案2】:

    视情况而定。三种解决方案,可能都不理想:

    • 如果您可以使用连续数字作为键(如果您已经有另一个企业 ID,则可以添加第二个键),在 Java 中生成一个随机键并按 id 查询。
    • 尝试ORDER BY RAND() 并获得前 60 个结果,但这不可移植,因为 RAND 或 RANDOM 不是 JPA 规范的一部分。
    • 选择所有记录并使用EntityManager.setFirstResult (random).setMaxResults (1) 滚动到随机行并重复60 次。

    【讨论】:

      【解决方案3】:

      有一个应用于实体的特殊属性__scatter__,map reduce 框架使用它来采样实体。

      It is mentioned in the javadoc here

      我无法找到有关其工作原理/应用时间的信息,但是在数据存储查看器中运行查询似乎会产生结果。然而,并非所有实体似乎都具有此属性。

      您可以尝试执行以下操作,看看效果如何:

      SELECT * FROM Kind order by __scatter__
      

      【讨论】:

      【解决方案4】:

      在首次部署代码时获取当前 unix 时间戳的常量。然后对于每条记录,保存另一列是当前的 unix 时间戳。现在每次查询随机记录时,在常量时间戳和当前时间戳之间生成随机的unix时间戳,并获取按生成的随机数排序的记录。

      【讨论】:

      • 实际上数据是我每月更新的 csv 文件的转储,所以这种机制并不真正适合我的需要
      • 我明白了。在这种情况下可能是序列号。记录将起作用并保存序列号。与每条记录。随机编号将在最小和最大序列号之间。尽管此解决方案的可行性取决于要求,但在特定情况下是否值得。
      【解决方案5】:

      我的想法有两个选择,第一个你可以缓存密钥,第一次只需要时间。

      其次,您可以在查询中使用 random 来获取任何随机记录

      【讨论】:

        猜你喜欢
        • 2011-03-01
        • 2011-09-05
        • 1970-01-01
        • 2012-12-11
        • 2019-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多