Моделирование голосов на GAE - PullRequest
3 голосов
/ 22 ноября 2010

Я пытаюсь определить наиболее эффективный способ создания голосовой сущности в хранилище данных GAE. Я хотел бы показать пользователю элемент управления для голосования за этот объект или значок, указывающий, что они уже проголосовали за него; то есть я спрашиваю "голосовал ли пользователь за эту организацию?" Допустим, у нас есть сущность Вопрос, за которую пользователь может проголосовать. Вот что я думаю сделать:

  1. Запрос моих сущностей Вопросов. Эти вопросы уже имеют заранее рассчитанный рейтинг, по которому я буду сортировать.
  2. Используйте сущность индекса отношений, которая является дочерней по отношению к сущности Вопрос. Запросите все вопросы, используя те же фильтры, что и # 1, где мой пользователь является членом этой сущности индекса отношений.
  3. Объединить результаты # 2 с # 1, установив для свойства hasVoted значение true для каждого найденного члена набора.

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

Ответы [ 3 ]

3 голосов
/ 23 ноября 2010

Вместо того, чтобы использовать индекс отношения, просто создайте дочернюю сущность для каждого пользователя, который проголосовал по этому вопросу. Сделайте key_name дочернего объекта идентификатором пользователя. Затем, чтобы определить, проголосовал ли пользователь y по вопросу с идентификатором x, просто выберите ключ (Вопрос: x / Голосование: y). Вы можете группировать это, чтобы получить несколько объектов для нескольких вопросов или пользователей тоже.

2 голосов
/ 23 ноября 2010

Я бы посмотрел Подслушано Пример приложения Google App Engine.

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

Об этом есть статья Google , а здесь Вы можете найти источники.

0 голосов
/ 22 ноября 2010

Чтобы избежать второго запроса, вы можете хранить все вопросов, за которые пользователь проголосовал, в одной сущности.Эта сущность может быть частью модели User или существовать в непосредственном отношении с сущностями User.

Затем вы можете загрузить эту информацию по мере необходимости (и сохранить ее в memcache, чтобы избежать загрузки хранилища данных)что вы можете быстро проверить, голосовал ли уже пользователь по какому-либо вопросу (большую часть времени не делая второго запроса).

Если пользователь может голосовать по действительно большому количеству вопросов, возможно, вам придетсярасширить эту идею.Вот набросок (не функционально завершенный) того, как вы могли бы пойти по простой схеме:

class UserVotes(db.Model):
    # key = key_name or ID of the corresponding user entity

    # if all of your question entities have IDs, then voted_on can be a list of 
    # integers; otherwise it can be a list of strings (key_name values)
    voted_on = db.ListProperty(int, indexed=False)  

# in your request handler ...
questions = ...
voted_on = memcache.get('voted-on:%s' % user_id)
if voted_on is None:
    voted_on = UserVotes.get_by_id(user_id)  # should do get_or_insert() instead
    memcache.set(...)
for q in questions:
    q.has_voted = q.key().id() in voted_on
...