3

在应用程序引擎(ndb 或 db)中处理计数的适当方法是什么?

我有两个项目,一个是 django-nonrel,另一个是纯 django 项目,但两者都需要能够进行查询并返回计数。结果可能大于 1,000。

我看到一些帖子说我可以使用分片计数器,但他们正在计算所有实体。我需要能够知道有多少实体具有以下属性 x=1,y=True,z=3

#Is this the appropriate way?
count = some_entity.gql(query_string).count(SOME_LARGE_NUMBER)
4

2 回答 2

5

数据存储不擅长这种查询,因为要进行权衡以使其分布式。这些包括相当慢的读取和非常有限的索引。

如果您需要一组有限的统计数据(用户数、文章数等),那么您可以在单独的实体中继续运行总计。这意味着当某些事情发生变化时,您需要执行两次写入(放置):一次用于更改的实体,一次用于更新 stats 实体。但是您只需要一次读取(获取)即可获取统计信息,而不是从多少实体中提取它们。

你可能对此感到不舒服,因为它违背了我们对标准化的了解,但它的效率要高得多,并且在许多情况下工作得很好。如果这很关键,您总是可以让 cron 作业定期执行查询以检查统计信息是否准确。

于 2012-06-27T00:56:42.697 回答
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 作业以使统计信息完美同步,最好将总计运行在单独的实体中。

于 2012-06-27T01:17:15.453 回答