Я пытаюсь смоделировать систему голосования в MongoDB.Вы можете представить это как систему голосования, похожую на Reddit.Требования:
- Голоса связаны с объектами
- Очень быстро проверить, проголосовал ли пользователь за объект.Приложению необходимо знать, проголосовал ли вошедший в систему пользователь за объект, в то время как оно просматривает список объектов, отображающих кнопки голосования.
- Самое главное, оно должно иметь возможность извлекать объекты, упорядоченные по их совокупным оценкам зазаданный период времени (последний час, день, месяц и т. д.) с разумной производительностью.
- Должен быть в состоянии поддержать тысячи голосов за объект.
Здесь я вижу два подхода (поправьте меня, если я ошибаюсь!):
- Вложите массив документов для голосования в каждый объект.Я бы, вероятно, сохранил ObjectId пользователя, который проголосовал, количество голосов и время голосования.Параметр voterId будет ключом для каждого встроенного документа голосования в массиве голосов для быстрого поиска хеша.
- Храните отдельную коллекцию голосов с голосами, которые ссылаются на объекты.
IМы также играли с идеей вложения голосов в «ведра», сгруппированные по часам в отдельном сборнике.
Нет.1 будет очень быстрым для требования № 2, но я не знаю, возможно ли в этом сценарии требование № 3.
Нет.2 будет медленнее для требования № 2, и я не уверен, как будет выглядеть производительность для требования № 3 / как она будет достигнута (уменьшение карты?).
По сути, мне кажется, что мне нужно начать с достаточно быстрого решения для требования № 3, а затем убедиться, что требование № 2 не слишком медленное.Идеи?
Потенциальное решение
Использовать встроенный метод.Добавьте параметр к каждому объекту для оценки по часам, по дням, по месяцам и т. Д. Добавьте еще один логический параметр недавно проголосовавший, недавно почасовой и недавний ежедневно.Создайте сценарий, который запускает map-lower для объектов для вычисления и обновления этих параметров.
Этот сценарий будет запускаться через cron в трех вариантах.
- 10-минутный интервал: рассчитать ежечасно-баллы для объектов с предыдущим часовым счетом> 0 ИЛИ для объектов, которые недавно проголосовали = true.Установите недавно-voted = false после запуска этого скрипта.Задайте недавний ежечасный = true.
- 3-часовой интервал: вычислите дневной счет для любых объектов, для которых недавно-часовой = истинный.Установить недавний почасовой = ложь.Установите недавний ежедневный = истинный.
- 24-часовой интервал: рассчитайте месячный счет для любых объектов, у которых недавний ежедневный = истинный.Установите недавний-ежедневный = ложный.
Идея состоит в том, чтобы минимизировать ненужную обработку объектов, не относящихся к выполняемому сценарию вычисления оценки (ежечасно следует запускать только для объектов, за которые проголосовалис момента последнего ежечасного запуска или объектов, за которые не проголосовали и которые необходимо сбросить до 0).Еще одним приятным преимуществом является то, что значения * -score нужно не просто вычислять на основе голосов объекта.Вы можете включить просмотр страниц, например, или что-то еще.Мысли об этом подходе?