【问题标题】:How does one get a count of rows in a Datastore model in Google App Engine?如何在 Google App Engine 的 Datastore 模型中获取行数?
【发布时间】:2010-10-19 13:32:20
【问题描述】:

我需要获取 App Engine 上特定模型的记录计数。如何做到这一点?

我批量上传了 4000 多条记录,但 modelname.count() 只显示 1000 条。

【问题讨论】:

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


    【解决方案1】:

    你应该使用Datastore Statistics:

    Query query = new Query("__Stat_Kind__");
    query.addFilter("kind_name", FilterOperator.EQUAL, kind);       
    Entity entityStat = datastore.prepare(query).asSingleEntity();
    Long totalEntities = (Long) entityStat.getProperty("count");
    

    请注意,以上内容不适用于开发数据存储区,但可用于生产(发布时)。

    我看到这是一篇旧帖子,但我添加了一个答案,以帮助其他人搜索相同的内容。

    【讨论】:

    • 我在您的代码的第一行收到此错误:“无法实例化类型查询”有什么想法吗?
    • 这只会返回我的一些实体,即使对于那些“计数”字段也是错误的。有没有办法强制刷新统计数据?
    【解决方案2】:

    从 1.3.6 版开始,计数查询不再有 1000 个上限。因此,您可以执行以下操作来获得超过 1,000 个的计数:

    count = modelname.all(keys_only=True).count()
    

    这将计算您的所有个实体,如果您有大量实体,这可能会相当慢。因此,您应该考虑调用 count() 并指定一些限制:

    count = modelname.all(keys_only=True).count(some_upper_bound_suitable_for_you)
    

    【讨论】:

    • 300 毫秒?你从哪里得到这个数字的?无论如何,这说明了为什么动态计算对象不是一个好主意。
    • 我猜他的意思是 30,000 毫秒。但事实并非如此,因为如果您因为批量上传器而这样做,您可能只是在 remote_api 上运行计数 - AFAIK 不受 30 秒超时的影响。
    • 我添加了更快的 keys_only=True
    • @dar,remote_api 中的计数仍受 30 秒超时限制。 remote_api 脚本本身不受超时限制,但单独的 API 调用仍然是。
    • @ryan 我知道,这就是我这么说的原因。
    【解决方案3】:
    count = modelname.all(keys_only=True).count(some_upper_limit)
    

    为了补充 dar 之前的帖子,必须指定这个 'some_upper_limit'。如果没有,默认计数仍将是最大 1000。

    【讨论】:

    • 好答案。我为此查看了日志时间,如果更新不是很频繁,使用 memcache 缓存结果似乎也是合理的。
    【解决方案4】:

    这是一个非常古老的线程,但为了防止其他人看到它,有 3 种方法可以完成此操作:

    1. 访问数据存储统计信息
    2. 在数据存储中保留一个计数器
    3. 分片计数器

    这些方法中的每一种is explained in this link

    【讨论】:

    【解决方案5】:

    在 GAE 中,当您拥有超过 1000 个对象时,计数总是会让您翻阅结果。处理此问题的最简单方法是向模型或不同的计数器表添加计数器属性,并在每次创建新对象时更新它。

    【讨论】:

      【解决方案6】:

      我的计数仍然达到了 1000 的限制,所以改编了 dar 的代码(我的代码有点快和脏):

      class GetCount(webapp.RequestHandler):
          def get(self):
              query = modelname.all(keys_only=True)
      
              i = 0
              while True:
                  result = query.fetch(1000)
                  i = i + len(result)
                  if len(result) < 1000:
                      break
                  cursor = query.cursor()
                  query.with_cursor(cursor)
      
              self.response.out.write('<p>Count: '+str(i)+'</p>')
      

      【讨论】:

        【解决方案7】:
        DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
        Query query = new Query("__Stat_Kind__");
        Query.Filter eqf = new Query.FilterPredicate("kind_name",
                                        Query.FilterOperator.EQUAL,
                                        "SomeEntity");
        query.setFilter(eqf);
        Entity entityStat = ds.prepare(query).asSingleEntity();
        Long totalEntities = (Long) entityStat.getProperty("count");
        

        【讨论】:

        • 只是为了澄清,将“SomeEntity”替换为您想要计数的类型的名称,其他一切都保持不变。此外,这仅在运行部署时有效,entityStat 将在本地运行时返回为 null。
        【解决方案8】:

        另一种解决方案是使用仅键查询并获取迭代器的大小。该解决方案的计算时间将随着条目的数量线性增加:

        Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
        KeyFactorykeyFactory = datastore.newKeyFactory().setKind("MyKind");
        Query query = Query.newKeyQueryBuilder().setKind("MyKind").build();
        int count = Iterators.size(datastore.run(query));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-25
          • 1970-01-01
          • 2015-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多