Google App Engine 统计

3
什么是在应用程序引擎(ndb或db)中处理计数的适当方式?
我有两个项目,一个是django-nonrel,另一个是纯django项目,但都需要能够获取查询并返回计数。结果可能大于1,000。
我看到一些帖子说我可以使用Sharded Counters,但它们正在计算所有实体。我需要知道具有以下属性x = 1,y = True,z = 3的实体数量。
#Is this the appropriate way?
count = some_entity.gql(query_string).count(SOME_LARGE_NUMBER)

1
@Nix:你需要的不同计数是有限/较少的数量吗?还是这个标准相当任意,基于用户输入? - Sologoub
@Nix,你可能已经读到了,ndb更酷炫。但是在查询/过滤和计数方面有一些小差异。我会给你举个例子。 - Lipis
2个回答

5
数据存储库不擅长这种查询,因为需要取舍以使其分布式。这些包括相当缓慢的读取和非常有限的索引。
如果您只需要有限的一组统计数据(用户数量、文章数量等),则可以在单独的实体中保持运行总数。这意味着在发生更改时需要进行两次写入(提交):一个用于更改的实体,另一个用于更新统计实体。但是,您仅需要一个读取(获取)来获取您的统计数据,而不是从多个实体中提取它们。
这可能会使您感到不舒服,因为它违反了我们所学习的规范化,但它效率更高,在许多情况下可以正常工作。如果这很重要,您始终可以定期使用 cron 作业进行查询,以检查统计数据的准确性。

3

如果您正在使用db.Model,以下是一种计算所有实体数量的方法,该方法包含一些可能超过1000个硬限制(如果仍适用)的筛选条件:

FETCH_LIMIT = 1000

def count_model(x=1, y=True, z=3):
  model_qry = MyModel.all(keys_only=True)
  model_qry.filter('x =', x)
  model_qry.filter('y =', y)
  model_qry.filter('z =', z)

  count = None
  total = 0
  cursor = None
  while count != 0:
    if cursor:
      count = model_qry.with_cursor(cursor).count()
    else:
      count = model_qry.count(limit=FETCH_LIMIT)

    total += count
    cursor = model_qry.cursor()
  return total

如果您要在请求中使用上述内容,那么可能会超时,请考虑改用任务队列

此外,如FoxyLad所建议的那样,为了性能原因最好将运行总数保存在单独的实体中,并将上述方法作为定期运行的cron作业来保持统计数据的完美同步。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接