2012-06-26 41 views
3

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

我有两个项目是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) 
+0

你使用'db'还是'ndb'? – Lipis

+1

@Nix是否存在您需要的有限/少量不同的计数,或者这是一个基于用户输入的相当随意的标准? – Sologoub

+0

@Nix ndb是更酷,因为你可能已经读过它.. :)但是,如何查询/过滤的东西和数数有一些小的差异..我会给你一个例子.. – Lipis

回答

5

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

如果您需要的统计数量有限(用户数量,文章数量等),那么您可以将总数保持在单独的实体中。这意味着当发生某些变化时,您需要进行两次写入(放入):一个用于更改的实体,另一个用于更新统计信息实体。但是你只需要一次读取(get)就可以得到你的统计数据,而不是无数的实体。

你可能会对此感到不舒服,因为它违背了我们所有人对标准化的了解,但它效率更高,在许多情况下工作正常。如果这是至关重要的,您可以随时定期做一个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 

如果你将在请求中使用上述内容,那么你可能会超时,所以请考虑使用Task Queues

同样作为FoxyLad提出,出于性能原因,并将上述方法作为定期运行的cron作业以使统计完美同步,将总数保持在单独的实体中会好得多。