2010-10-22 100 views
3

嗨我想建立一個應用程序,其模型類似於下面的: - (雖然它很容易將兩個模型合併成一個並使用它們,但這是不可行的在實際的應用程序)建模的谷歌數據存儲/ python

class User(db.Model): 
    username=db.StringProperty() 
    email=db.StringProperty() 

class UserLikes(db.Model): 
     username=db.StringProperty() 
     food=db.StringProperty() 

登錄後objective-用戶輸入自己喜歡,進而應用程序返回所有其他用戶誰喜歡食物的食物。 現在假設用戶Alice輸入她喜歡的「Pizzas」,它將被存儲在數據存儲區中。她註銷並重新登錄。此時,我們向數據存儲庫查詢她喜歡的食物,然後再次查詢所有喜歡該食物的用戶。如你所見,這是兩個數據存儲查詢,這不是最好的方法。我相信肯定會有更好的方式來做到這一點。有人可以請幫助。

[更新: - 或者可以這樣做,我改變第二個模型,使用戶名變成一個多值屬性,其中所有用戶都喜歡那個食物可以存儲..但是我有點不清楚]

[編輯:-Hi感謝您的回覆,但我發現這兩個解決方案在這裏有點矯枉過正。我試着像下面這樣做。請你看看這個和善意的建議。我保持相同的兩個表,但是改變了他們象下面這樣: -

class User(db.Model): 
    username=db.StringProperty() 
    email=db.StringProperty() 

class UserLikes(db.Model): 
    username=db.ListProperty(basestring) 
    food=db.StringProperty() 

現在,當用戶更新同樣的食物,他們喜歡,它就會像存儲

「比薩」 ---->「愛麗絲」 ,「鮑勃」

而且我的數據庫查詢檢索數據變得很容易在這裏

query=db.Query(UserLikes).filter('username =','Alice').get() 

,我就可以遍歷,就像這樣

for elem in query.username: 
      print elem 

現在,如果有喜歡的下面兩種食物: -

'pizza' ----> 'Alice','Bob' 
'bacon'----->'Alice','Fred' 

我用的是相同的查詢同上,迭代查詢,然後將用戶名。

我對此很新,意識到這可能是錯誤的。請推薦!

回答

2

除了您擁有的關係模型,您可以根據您的確切用例以其他兩種方式處理此問題。你有更好的主意,使用ListProperty。在一些背景下查看Brett Slatkin的taslk Relation Indexes

你可以使用包含的食物清單上的用戶子實體(關聯索引):

class UserLikes(db.Model): 
    food = db.StringListProperty() 

然後,當你創建一個UserLikes實例,您將定義它涉及到作爲父用戶:

likes = UserLikes(parent=user) 

這可以讓你查詢誰喜歡漂亮特定食物的其他用戶:

like_apples_keys = UserLikes.all(keys_only=True).filter(food='apples') 
user_keys = [key.parent() for key in like_apples_keys] 
users_who_like_apples = db.get(user_keys) 

然而,什麼可能適合你的應用程序更好,將是使關係食品的孩子:

class WhoLikes(db.Model): 
    users = db.StringListProperty() 

設置KEY_NAME創建時等食品的名稱:

food_i_like = WhoLikes(key_name='apples') 

現在,讓誰喜歡蘋果的所有用戶:

apple_lover_key_names = WhoLikes.get_by_key_name('apples') 
apple_lovers = UserModel.get_by_key_names(apple_lover_key_names.users) 

要得到誰喜歡同樣的東西,用戶的所有用戶:

same_likes = WhoLikes.all().filter('users', current_user_key_name) 
like_the_same_keys = set() 
for keys in same_likes: 
    like_the_same_keys.union(keys.users) 
same_like_users = UserModel.get_by_key_names(like_the_same_keys) 

如果您將有很多喜歡者,或許多擁有相同喜好的用戶,則需要對流程進行一些調整。您將無法獲取1,000位用戶。

+0

該鏈接的精彩教程..謝謝..請在上面的帖子中看看我編輯的解決方案。我相信我應該做些簡單的事情! – Rasmus 2010-10-22 17:50:41

+1

你有效地做我建議的。最大的區別之一是您正在使用屬性來存儲'food'的值而不是使用key_name。當您嘗試查找喜歡食物'x'的所有用戶時,使用key_name會更有效率。但是,如果您的列表中將包含超過幾千個用戶,則最容易包含一個屬性。確保您使用的是Appstats(http://code.google.com/appengine/docs/python/tools/appstats.html),以便您可以準確瞭解幕後發生的情況。 – 2010-10-24 04:49:12

+0

Thanks!Robert .. – Rasmus 2010-10-26 02:20:31

1

食物和用戶關係是一個所謂的Many-to-Many relationship用Join表格處理;在這種情況下,鏈接用戶和食物的db.Model。 事情是這樣的:

class User(db.Model): 
    name = db.StringProperty() 

    def get_food_I_like(self): 
    return (entity.name for entity in self.foods) 

class Food(db.Model): 
    name = db.StringProperty() 

    def get_users_who_like_me(self): 
    return (entity.name for entity in self.users) 

class UserFood(db.Model): 
    user= db.ReferenceProperty(User, collection_name='foods') 
    food = db.ReferenceProperty(Food, collection_name='users') 

對於給定用戶的實體,你可以檢索與首選食物:

userXXX.get_food_I_like() 

對於給定的食品的實體,您可以檢索用戶像與食物:

foodYYY.get_users_who_like_me() 

還有另一種方法來處理在db.ListProperty()中存儲密鑰列表的多對多關係。

class Food(db.Model): 
    name = db.StringProperty() 

class User(db.Model): 
    name = db.StringProperty() 
    food = db.ListProperty(db.Key) 

請記住,ListProperty限制爲5。000鍵或者再次,你不能添加完全適合連接表的有用屬性(例如:表示用戶喜歡食物的星星數量)。

+0

使用'get_food_I_like'函數時要非常小心。它會爲每一個喜歡這種食物的用戶做一個額外的數據存儲調用。 – 2010-10-22 15:02:03

+0

感謝systempuntoout ..但是這再次使用一個數據存儲區調用。例如: - 用戶登錄後,我將不得不做一些類似food = userxx.get_food_i_like()的事情,然後再找到所有喜歡這些食物的用戶,用戶= foodYYY.get_users_who_like_me()。目標是當用戶登錄時將所有用戶顯示在小顯示器上。我嘗試了一些可行的方法,但後來我可能錯了,如果有人可以看一下它會很好用 – Rasmus 2010-10-22 16:00:45

+0

請求您看看解決方案我在原來的post.Please諮詢! – Rasmus 2010-10-22 17:51:32