Лучший способ смоделировать систему голосования в MongoDB - PullRequest
12 голосов
/ 13 августа 2011

Я пытаюсь смоделировать систему голосования в MongoDB.Вы можете представить это как систему голосования, похожую на Reddit.Требования:

  1. Голоса связаны с объектами
  2. Очень быстро проверить, проголосовал ли пользователь за объект.Приложению необходимо знать, проголосовал ли вошедший в систему пользователь за объект, в то время как оно просматривает список объектов, отображающих кнопки голосования.
  3. Самое главное, оно должно иметь возможность извлекать объекты, упорядоченные по их совокупным оценкам зазаданный период времени (последний час, день, месяц и т. д.) с разумной производительностью.
  4. Должен быть в состоянии поддержать тысячи голосов за объект.

Здесь я вижу два подхода (поправьте меня, если я ошибаюсь!):

  1. Вложите массив документов для голосования в каждый объект.Я бы, вероятно, сохранил ObjectId пользователя, который проголосовал, количество голосов и время голосования.Параметр voterId будет ключом для каждого встроенного документа голосования в массиве голосов для быстрого поиска хеша.
  2. Храните отдельную коллекцию голосов с голосами, которые ссылаются на объекты.

IМы также играли с идеей вложения голосов в «ведра», сгруппированные по часам в отдельном сборнике.

Нет.1 будет очень быстрым для требования № 2, но я не знаю, возможно ли в этом сценарии требование № 3.

Нет.2 будет медленнее для требования № 2, и я не уверен, как будет выглядеть производительность для требования № 3 / как она будет достигнута (уменьшение карты?).

По сути, мне кажется, что мне нужно начать с достаточно быстрого решения для требования № 3, а затем убедиться, что требование № 2 не слишком медленное.Идеи?


Потенциальное решение

Использовать встроенный метод.Добавьте параметр к каждому объекту для оценки по часам, по дням, по месяцам и т. Д. Добавьте еще один логический параметр недавно проголосовавший, недавно почасовой и недавний ежедневно.Создайте сценарий, который запускает map-lower для объектов для вычисления и обновления этих параметров.

Этот сценарий будет запускаться через cron в трех вариантах.

  1. 10-минутный интервал: рассчитать ежечасно-баллы для объектов с предыдущим часовым счетом> 0 ИЛИ для объектов, которые недавно проголосовали = true.Установите недавно-voted = false после запуска этого скрипта.Задайте недавний ежечасный = true.
  2. 3-часовой интервал: вычислите дневной счет для любых объектов, для которых недавно-часовой = истинный.Установить недавний почасовой = ложь.Установите недавний ежедневный = истинный.
  3. 24-часовой интервал: рассчитайте месячный счет для любых объектов, у которых недавний ежедневный = истинный.Установите недавний-ежедневный = ложный.

Идея состоит в том, чтобы минимизировать ненужную обработку объектов, не относящихся к выполняемому сценарию вычисления оценки (ежечасно следует запускать только для объектов, за которые проголосовалис момента последнего ежечасного запуска или объектов, за которые не проголосовали и которые необходимо сбросить до 0).Еще одним приятным преимуществом является то, что значения * -score нужно не просто вычислять на основе голосов объекта.Вы можете включить просмотр страниц, например, или что-то еще.Мысли об этом подходе?

Ответы [ 2 ]

2 голосов
/ 15 августа 2011

Ознакомьтесь с рецептом «Голосование с атомарными операторами» в Кулинарной книге Монго: http://cookbook.mongodb.org/patterns/votes/. В нем не рассказывается, как реализовать агрегацию, но вы могли бы сделать это, сделав отдельные объекты, представляющие объекты для голосовать, но за определенный период времени.

0 голосов
/ 13 августа 2011

Если вы используете ruby, есть плагин votable_mongo для Mongoid и MongoMapper.

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