Следуйте структуре модели хранилища данных в AppEngine - Упорядочить подписчиков по дате - PullRequest
5 голосов
/ 10 февраля 2011

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

Я сохраняю следующие отношения следующим образом:

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, follow = 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)

Однако таким образом мне придется обрабатывать список контактов: - Я должен извлечь ключи пользователя и date_created из каждой строки в StringList () -Затем я могу упорядочить список пользовательских ключей по дате создания

3) Последнее решение (явно не эффективное): сохранить исходную структуру БД и сохранить действия пользователя в отдельной модели - каждое последующее действие хранится отдельнос полем date_created.Используйте эту таблицу только для того, чтобы упорядочить список подписчиков по дате.Это, конечно, означает, что я сделаю два размещения хранилища данных - одно в Contacts (), а другое в FollowNewsFeed () следующим образом:

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

Любые идеи о том, как лучше всего с этим справиться, высоко ценятся)

Спасибо!

1 Ответ

3 голосов
/ 11 февраля 2011

Я бы использовал модель для сопоставления пользователя с его целью, а не со списком:

  1. Вставка нового экземпляра или удаление существующего, вероятно, будет быстрее, чем изменение огромногосписок и сохранение его.Кроме того, по мере увеличения размера отслеживаемого объекта вы можете запрашивать подмножество списка, а не извлекать его все (см. Ниже))так же беспокоиться о необходимости перепроектировать и выдумывать списки в будущем.

  2. Не нужно беспокоиться об ограничениях индекса со списками (каждый элемент занимает ячейку до 5000) .

К сожалению, вы, вероятно, достигнете другого предела гораздо раньше :

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

Это означает, что каждый элемент будет занимать слот [ex.in (1,2,3) = 3 слота].Таким образом, даже при относительно небольшом количестве (~ 30 подписчиков) вам потребуется совершить несколько поездок в базу данных и добавить результаты.

Предполагая, что люди не хотят сходить с ума на своей странице, загружаясь сотни лети времени вам понадобится какое-то ограничение на количество людей, которым они могут следовать.При 100 отслеживаемых людях вам потребуется 4-5 поездок и сортировка данных в вашем приложении или на стороне клиента с помощью javascript.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...