2011-02-10 11 views
5

在我的應用中,用戶可以關注其他用戶,並在他們關注的人員執行活動時獲取更新。關注AppEngine上的數據存儲模型結構 - 按日期訂購關注者

我存儲後續關係,以這種方式:

class User(db.Model): 
    ''' User details ''' 
    username = db.StringProperty() 

class Contacts(db.Model): 
    '''Store users contacts 
     parent= User (follower) 
     key_name= Users username (follower) 
     contacts = A list of keys of Users that a User follows ''' 
    contacts = db.ListProperty(db.Key) 
    last_updated = db.DateTimeProperty(auto_now=True) 

獲取追隨者和用戶,用戶如下(追隨者&以下):

'''Get Users that my_user follows''' 
my_user = User().all().fetch(1) 
contacts = Contacts.get_by_key_name(my_user.username).contacts 

''' get my_user followers - copied from an answer here on stackoverflow ''' 
follower_index = models.Contacts.all(keys_only=True).filter('contacts =',my_user) 
follower_keys = [f.parent() for f in follower_index] 
followers = db.get(follower_keys) 

所以,我想訂購my_user追隨者通過跟隨日期(我不追蹤上述模型),但我不知道什麼是最好的方式來做到這一點。下面是我能想到的選擇:

1)替代聯繫人的當前結構(db.Model),使用「橋」的模式:

class Contacts(db.Model): 
    follower = db.ReferenceProperty(User) 
    following = db.ReferenceProperty(User) 
    date_created = db.DateTimeProperty(auto_now_add=True) 

不過,我還是要搞清楚如何確保我有獨特的追隨者 - >以下實體:follower = user1,following = user2不應該重複。我可以做到這一點,如果我應用2個過濾器我認爲我的查詢。

2)保持當前的模型結構,但代替具有密鑰的聯繫人(列表db.Model),存儲的元組:[user_key,DATE_CREATED]如下:

class Contacts(db.Model): 
     '''Store users contacts 
      parent= User (follower) 
      key_name= Users username (follower) 
      contacts = A list of Tuples: User.key(), date_created ''' 
     contacts = db.StringListProperty() 
     last_updated = db.DateTimeProperty(auto_now=True) 

然而,這這樣,我將不得不處理聯繫人列表: - 我要提取的用戶密鑰和從StringList的(每串DATE_CREATED) - 然後,我可以通過創建日期順序用戶密鑰列表

3 )最後的解決方案(顯然不高效):保持原始數據庫結構,並將用戶關注活動存儲在單獨的模式中l - 每個關注操作都會與date_created字段分開存儲。只能使用此表格才能按日期排列用戶關注者列表。當然,這意味着我會做兩個數據存儲看跌期權 - 一個聯繫人(),另一個FollowNewsFeed()如下:

Class FollowNewsFeed(db.Model): 
    ''' parent = a User follower''' 
    following = db.ReferenceProperty(User) 
    date_created = db.DateTimeProperty(auto_add_now=True) 

上解決這個問題的最好辦法任何見解的高度讚賞:)

謝謝!

回答

3

我會用一個模型來從用戶到自己的目標映射而不是一個列表:

  1. 插入一個新的實例或刪除現有的將可能是比修改一個巨大的名單,並重新保存它更快。隨着隨之而來的大小增長,您可以查詢列表的一個子集,而不是將其全部提取(請參閱下面的原因)。

  2. 您可以獲得額外的屬性空間,不必擔心需要重新設計並在列表中添加名單。

  3. 不必擔心列表(each item takes up a slot, up to 5000)的索引限制。

不幸的是,你可能會打another limit much sooner

A single query containing != or IN operators is limited to 30 sub-queries. 

這意味着每一個元素會消耗插槽[EX。 in (1,2,3) = 3個插槽]。因此,即使數量相對較少(約30人),您也需要多次訪問數據庫並追加結果。

假設人們不想在他們的頁面上瘋狂地花費數百年來加載和計時,您需要對他們可以關注的人數進行一些限制。在100人被跟蹤時,你需要一個好的4-5次旅行,並且必須通過javascript在你的應用程序或客戶端對數據進行排序。

+0

謝謝!有趣的 - 我沒有想到子查詢的限制。這是我必須要處理的另一個問題,特別是如您所提及的,我需要按日期對結果集進行排序 - 所以我需要在將它顯示給用戶之前將其全部放入一個列表中。 – yasser 2011-02-11 01:52:19