A good data model for finding a user's favorite stories

Posted by wings on Stack Overflow See other posts from Stack Overflow or by wings
Published on 2009-10-13T18:36:46Z Indexed on 2010/04/24 2:03 UTC
Read the original article Hit count: 253

Original Design

Here's how I originally had my Models set up:

class UserData(db.Model):
    user = db.UserProperty()
    favorites = db.ListProperty(db.Key) # list of story keys
    # ...

class Story(db.Model):
    title = db.StringProperty()
    # ...

On every page that displayed a story I would query UserData for the current user:

user_data = UserData.all().filter('user =' users.get_current_user()).get()
story_is_favorited = (story in user_data.favorites)

New Design

After watching this talk: Google I/O 2009 - Scalable, Complex Apps on App Engine, I wondered if I could set things up more efficiently.

class FavoriteIndex(db.Model):
    favorited_by = db.StringListProperty()

The Story Model is the same, but I got rid of the UserData Model. Each instance of the new FavoriteIndex Model has a Story instance as a parent. And each FavoriteIndex stores a list of user id's in it's favorited_by property.

If I want to find all of the stories that have been favorited by a certain user:

index_keys = FavoriteIndex.all(keys_only=True).filter('favorited_by =', users.get_current_user().user_id())
story_keys = [k.parent() for k in index_keys]
stories = db.get(story_keys)

This approach avoids the serialization/deserialization that's otherwise associated with the ListProperty.

Efficiency vs Simplicity

I'm not sure how efficient the new design is, especially after a user decides to favorite 300 stories, but here's why I like it:

  1. A favorited story is associated with a user, not with her user data

  2. On a page where I display a story, it's pretty easy to ask the story if it's been favorited (without calling up a separate entity filled with user data).

    fav_index = FavoriteIndex.all().ancestor(story).get()
    fav_of_current_user = users.get_current_user().user_id() in fav_index.favorited_by
    
  3. It's also easy to get a list of all the users who have favorited a story (using the method in #2)

Is there an easier way?

Please help. How is this kind of thing normally done?

© Stack Overflow or respective owner

Related posts about google-app-engine

Related posts about python