Как лучше всего моделировать опросы? - PullRequest
2 голосов
/ 14 сентября 2011

Домен выглядит следующим образом:

class Poll(db.Model):
    question = db.StringProperty()
    ...

class Choice(db.Model):
    poll = db.ReferenceProperty(Poll)
    choice = db.StringProperty()

class Vote(db.Model):
    user = db.ReferenceProperty(User)
    choice = db.ReferenceProperty(Choice)

(Это на самом деле не окончательная модель, это просто псевдограмма)

Вещи, которые мне нужно запросить:

  • Общее количество голосов для каждого опроса на экране
  • Общее количество голосов для каждого варианта для каждого опроса на экране
  • Если проголосовал текущий пользователь, для каждого опроса

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

Не могли бы вы помочь мне смоделировать мои данные?

Спасибо


Редактировать: Спасибо @Ник Джонсон Я могу более точно описать мою проблему, он предложил эту схему

class Poll(db.Model):
    question = db.StringProperty(indexed=False, required=True)
    choices = db.StringListProperty(indexed=False, required=True)
    votes = db.ListProperty(int, indexed=False, required=True)

class Vote(db.Model):
    # Vote is a child entity of Poll, so doesn't need an explicit reference to it
    # Vote's key name is the user_id, so users can only vote once
    user = db.ReferenceProperty(User, required=True)
    choice = db.IntegerProperty(required=True)

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

class PollIndex(db.Model):
    # PollIndex is child of Poll
    voters = db.ListProperty(db.Key)
    voters_choices = db.ListProperty()
    # other search parameters

Тогда, когда мне нужно запросить список опросов, я могу сделать это только с 2 запросами:

# get keys from pollindex where user is not there
# get keys from pollindex where user is there
# grabb all the polls

Еще одна крутая вещь, что если избирателиувеличение размера я могу динамически добавить больше PollIndexes

Что вы думаете об этом подходе?

1 Ответ

2 голосов
/ 14 сентября 2011

Ответ в некоторой степени зависит от ожидаемой максимальной частоты обновлений в опросе. Сначала я предполагаю, что он будет довольно ограниченным (<1 в секунду, типично, с пиками до 10 в секунду). </p>

Ваш дизайн в основном в порядке, за исключением нескольких настроек:

  • Не храните варианты как отдельную сущность, просто сохраняйте их как список в опросе
  • Сохранение промежуточного количества голосов в объекте опроса для быстрого поиска

С этими изменениями ваша модель выглядит примерно так:

class Poll(db.Model):
  question = db.StringProperty(indexed=False, required=True)
  choices = db.StringListProperty(indexed=False, required=True)
  votes = db.ListProperty(int, indexed=False, required=True)

class Vote(db.Model):
  # Vote is a child entity of Poll, so doesn't need an explicit reference to it
  # Vote's key name is the user_id, so users can only vote once
  user = db.ReferenceProperty(User, required=True)
  choice = db.IntegerProperty(required=True)

# Here's how we record a vote
def record_vote(poll_key, user, choice_idx):
  # We assume 'user' is an instance of a datastore model, and has a property 'user' that is
  # a users.User object
  poll = Poll.get(poll_key)
  vote = Vote.get_by_key_name(user.user.user_id(), parent=poll)
  if vote:
    # User has already voted
    return
  vote = Vote(key_name=user.user.user_id(), parent=poll, user=user)
  poll.votes[choice_idx] += 1
  db.put([vote, poll])

Если вам нужна более высокая пропускная способность, вы должны изменить запись Vote, чтобы она не была дочерней по отношению к Poll (и изменить имя ее ключа, чтобы включить как идентификатор опроса, так и идентификатор пользователя), а затем либо использовать счетчики обратной записи с Memcache или очередью извлечения для объединения результатов в обновления итогов опроса.

...