Интересует сама логика реализации.
У меня на данный момент существует данный рейтинг, но при перерасчете который выполняется каждый час создается очень большая нагрузка на базу данных, в связи с этим нужны какие то альтернативы.
Как сейчас все работает:
У меня есть коллекция, допустим analytics, со сбором статистики, куда прописывается URL с просмотром документа
{
_id: ID,
page: "http:......post/id/",
count: 1, // поле лишнее, просто для наглядности
createdAt: new Date()
}
Если пользователь просматривает пост, то идет запись в analytics.
Далее я каждый час обновляю данные по крону и собираю информацию сколько пользователей просмотрело определенные URL (суммирую просмотры).
За День этот URL просмотрело N пользователей
За Неделю этот URL просмотрело N пользователей
За Месяц этот URL просмотрело N пользователей
И таких разных URL тысячи.
В коллекции порядка 10 миллионов последних записей, более старые удаляются по крону, так как нет смысла их хранить.
Так вот, даже выборка просмотров за один день создает приличную нагрузку на сервер базы данных.
Пример выборки
return Analytics.aggregate([
{
$match: {
count: { $exists: !0 },
createdAt: { $gte: new Date(new Date().setDate(new Date().getDate() - 1)) }
}
//....
{
$group: {
_id: "$page",
count: {
$sum: "$count"
}
}
}
])
С индексами все в порядке, они есть...
Затем банально сумму просмотров я записываю в коллекцию с постами, обновляю документ, а именно поле popular
//db.posts
{
_id: ID,
url: String,
popular: {
day: Number,
week: Number,
month: Number
}
}
Как можно перестроить/переделать рейтинг для меньшей нагрузки на базу. Может доп. коллекцию создать для этого дела, но придется как то регулировать актуальность данных для расчета времени просмотров, в общем мне совсем не понятна альтернативная логика текущей.
Любые советы по этому поводу будут полезны для меня.