2012-06-26 179 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作業以使統計完美同步,將總數保持在單獨的實體中會好得多。