2012-09-27 85 views
0

我使用的是與python 2.7和webapp2框架的appengine。我是而不是使用ndb.model。appengine多對多的字段更新值和查找有效

我有以下型號:

class Story(db.Model); 
    name = db.StringProperty() 

class UserProfile(db.Model): 
    name = db.StringProperty() 
    user = db.UserProperty() 

class Tracking(db.Model): 
    user_profile = db.ReferenceProperty(UserProfile) 
    story = db.ReferenceProperty(Story) 
    upvoted = db.BooleanProperty() 
    flagged = db.BoolenProperty() 

用戶可以給予好評和/或國旗的故事,但只有一次。因此我想出了上述模型。 現在,當用戶點擊upvote鏈接,在數據庫上我嘗試看看,如果用戶還沒有投票的,所以我會盡力做到以下幾點:

  1. 與他的id來獲取用戶實例作爲up = db.get(db.Key.from_path('UserProfile', uid))

  2. 然後拿到故事爲例說明如下s_ins = db.get(db.Key.from_path('Story', uid))

  3. 現在是,檢查是否存在基於這兩個Tracking如果那就不要轉允許投票,否則允許他投票並且更新跟蹤實例。

什麼是最便捷的方式獲取給出的user_profilestory一個id(db.key().id())一個Tracking實例?

什麼是被給保存一個Tracking模型用戶配置文件ID和故事ID最便捷的方式?

有沒有更好的方法來實現跟蹤?

回答

1

您可以嘗試使用密鑰列表與具有跟蹤/用戶/故事一個單獨的條目跟蹤:當你想看到

class Story(db.Model); 
    name = db.StringProperty() 

class UserProfile(db.Model): 
    name = db.StringProperty() 
    user = db.UserProperty() 

class Tracking(db.Model): 
    story = db.ReferenceProperty(Story) 
    upvoted = db.ListProperty(db.Key) 
    flagged = db.ListProperty(db.Key) 

因此,如果upvoted對於給定的故事用戶:

Tracking.all().filter('story =', db.Key.from_path('Story', uid)).filter('upvoted =', db.Key.from_path('UserProfile', uid)).get(keys_only=True) 

現在唯一的問題是upvoted/flagged列表的大小不能變得太大(我認爲這個限制是5000),所以你必須讓一個類來管理這個(也就是說,當添加到upvoted /被標記的列表,檢測X條目是否存在,如果是,則啓動一個新的追蹤對象來保存添加al值)。您還必須完成這項交易,並且您需要每秒寫入1次閾值。這可能會也可能不是問題,具體取決於您的預期用例。圍繞寫閾值的方法是使用拉隊列實現upvotes/flags,並有一個cron作業,根據需要提取並批量更新跟蹤對象。

這種方法有它的優點/缺點。最明顯的缺點是我剛剛列出的。然而,專業人員可能是值得的。您可以從單個列表(或多個取決於故事的流行程度)中獲得一個完整列出的用戶列表/標記故事的用戶列表。您可以獲得數據存儲的查詢數量更少的完整用戶列表。此方法還應占用較少的存儲空間,索引和元數據空間。另外,將用戶添加到跟蹤對象會更便宜,而不是爲每個屬性編寫新的對象+ 2次寫入,您只需支付1次寫入對象+ 2次寫入列表中的條目(9次寫入3次寫入爲將用戶添加到預先存在的追蹤報道,或9對7對未經跟蹤報道)

0

你提出的建議聽起來很合理。

請勿使用應用引擎生成的密鑰進行跟蹤。由於故事/用戶的組合應該是唯一的,因此創建自己的密鑰作爲故事/用戶的組合。類似於

tracking = Tracking.get_or_insert(str(story.id) + "-" + str(user.id), **params) 

如果您知道故事/用戶,那麼您始終可以通過鍵名獲取跟蹤。

+0

可以ü請詳細說明(STR(story.id)+ 「 - 」 +'STR(user.id),** PARAMS )' – whatf

+0

你可以使用任意的字符串,所以只需通過將用戶標識附加在一起即創建一個,即「1234-890123」。檢查參數文檔get_or_insert()以獲取參數(並且還需要驗證是否創建了新實體,或者獲取是否成功)。 – dragonx