Как смоделировать поток подписчика в Appengine? - PullRequest
3 голосов
/ 24 мая 2010

Я пытаюсь создать таблицы для построения отношений с последователем.

Скажем, у меня есть поток из 140char записей, в которых есть пользователь, хэштег и другой текст.

Пользователи следуют за другими пользователями иможет также следовать за хэштегами.

Я обрисовываю в общих чертах способ, которым я разработал это ниже, но в моем дизайне есть два ограничения.Мне было интересно, есть ли у других более умные способы достижения той же цели.

Проблемы с этим

  1. Список подписчиков копируется для каждой записи
  2. Если новый подписчик добавлен или удален, «все» записи должны быть обновлены.

Код

class HashtagFollowers(db.Model):
    """
    This table contains the followers for each hashtag
    """
    hashtag = db.StringProperty()
    followers = db.StringListProperty()

class UserFollowers(db.Model):
    """
    This table contains the followers for each user
    """
    username = db.StringProperty()
    followers = db.StringListProperty()

class stream(db.Model):
    """
    This table contains the data stream
    """
    username = db.StringProperty()
    hashtag = db.StringProperty()
    text = db.TextProperty()

    def save(self):
        """
        On each save all the followers for each hashtag and user
        are added into a another table with this record as the parent
        """
        super(stream, self).save()
        hfs = HashtagFollowers.all().filter("hashtag =", self.hashtag).fetch(10)
        for hf in hfs:
            sh = streamHashtags(parent=self, followers=hf.followers)
            sh.save()
        ufs = UserFollowers.all().filter("username =", self.username).fetch(10)
        for uf in ufs:
            uh = streamUsers(parent=self, followers=uf.followers)
            uh.save()



class streamHashtags(db.Model):
    """
    The stream record is the parent of this record
    """
    followers = db.StringListProperty() 

class streamUsers(db.Model):
    """
    The stream record is the parent of this record
    """
    followers = db.StringListProperty()

Now, to get the stream of followed hastags 

    indexes = db.GqlQuery("""SELECT __key__ from streamHashtags where followers = 'myusername'""")
    keys = [k,parent() for k in indexes[offset:numresults]]
    return db.get(keys)

Есть ли более разумный способ сделать это?

Ответы [ 4 ]

5 голосов
/ 30 мая 2010

Проблема, которую вы хотите решить, называется проблемой разветвления.

Бретт Слаткин из команды Google App Engine рассказал об эффективном / масштабируемом решении проблемы разветвления в App Engine.Вы можете найти видео беседы здесь:

http://code.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html

1 голос
/ 26 июня 2010

Да, это проблема разветвления, как отметили другие, и заинтересованные лица должны посмотреть на выступление Бретта Слаткина.

Однако я поднял 2 конкретных ограничения, т. Е.

  • Список подписчиков копируется для каждой записи

Это, как говорится, не ошибка, а особенность. На самом деле, именно таким образом разворачиваются весы на приборах.

  • Если новый подписчик добавлен или удален, «все» записи должны быть обновлены.

Либо это ИЛИ ничего не делает, поэтому будущие записи не отслеживаются. Другими словами, человек не просто следует за потоками людей, он следует за потоком людей в данное время. Поэтому, если во второй день вы отмените подписку, ваш поток подписчиков будет по-прежнему отображать записи от пользователя, пришедшего в первый день, но не во второй день и далее. [Примечание: это отличается от того, как это делает твиттер]

0 голосов
/ 24 мая 2010

Я не уверен, как это сделать в Google App-Engine, но я хотел бы рассмотреть одну схему базы данных:

Tables:
    User    -- a table of users with their attributes
    HashTag -- a table of HashTags with their attributes
    Follows -- a table that defines who follows whom

Columns in the Follows table:
    followed int,         -- the id of the followed entity (could be 
                             User or Hashtag)
    followed_is_user bit, -- whether the followed item is a User
    followed_is_tag bit,  -- whether the followed item is a HashTag
    follower int          -- the id of the follower (this can only be 
                             a User so you may want to make this a foreign 
                             key on the User table)

Возможно, вы могли бы сжать два битовых столбца в один, но это позволило бы вам добавить другие вещи, которые пользователи могли бы использовать в будущем.

0 голосов
/ 24 мая 2010

Вы можете использовать свойство reference , а затем иметь общую таблицу со своими подписчиками, на которую вы ссылаетесь

...