Google App Engine很重要

时间:2012-06-26 23:06:54

标签: python google-app-engine

在app引擎(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)

2 个答案:

答案 0 :(得分:5)

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

如果您需要一组有限的统计信息(用户数,文章数等),那么您可以在一个单独的实体中继续运行总计。这意味着当需要更改时,您需要执行两次写入(puts):一次用于更改的实体,另一次用于更新stats实体。但是你只需要一个读取(get)来获取统计数据,而不是从中提炼出很多实体。

你可能对此感到不舒服,因为它违背了我们所知道的关于规范化的内容,但它效率更高,并且在许多情况下工作正常。如果这是至关重要的,您可以随时定期执行cron作业以查看统计信息是否准确。

答案 1 :(得分: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

如果您要在请求中使用上述内容,则可能会超时,因此请考虑使用Task Queues

同样如FoxyLad所建议的那样,出于性能原因将上述方法作为一个cron作业定期运行以使统计数据处于完美同步状态,最好在一个单独的实体中保持运行总数。