Алгоритмы: Правльный рейтинг новостей в каталоге DLE
nowheremany 13.02.2013 Блог 7941 2 комментария
Решил опубликовать небольшое описание как сделать правильный рейтинг новостей в каталоге DLE.
Почему именно в каталоге? Ответ чуть ниже...
Итак что сейчас есть в ДЛЕ: Рейтинг строится путём выбора новостей за определённый промежуток времени и сортируется по параметру популярности (просмотрам, рейтингу новости, кол-во комментариев). Этот способ подходит для новостей, у которых есть определённый момент жизненного цикла, в котором эта новость перестаёт быть актуальной.
Для рейтинга определённых каталогов такой подход не логичен и он даже мешает, потому что в каталоге новости не имеют такого параметра как актуальность. Именно про рейтинг таких каталогов и пойдет речь.
Итак как можно выйти из положения? Выбирать все новости и их сортировать по популярности.
Такой подход имеет право на существование, но у него есть большой недостаток: У старой новости рейтинг популярности очень большой и его вряд ли перепрыгнут новости, недавно добавленные.
Исходные Данные
title newsread
нов1 10
нов2 20
нов3 400
нов4 800
Исходя из этого логично сделать поле в БД, в котором бы мы хранили параметр популярности с предыдущего периода, к примеру на начало недели. Конечно можно пойти по другому пути и хранить в БД все просмотры с датой и получать их сумму, но такой подход захламляет базу да и нагрузка большая.
Отвлёкся... Собственно добавляем поле, все просто:
ALTER TABLE `dle_post` ADD `rate` MEDIUMINT( 8 ) NOT NULL DEFAULT '0'
Вуаля у нас есть поле в БД.
В запросе на заполнение поля тоже ничего сложного нет:
UPDATE `dle_post` SET `rate` = `news_read`;
Почему news_read? Лично для себя я взял за основу просмотры новости.
Ну и запрос на получение данных:
SELECT (news_read-rate) as rateN, title FROM dle_post ORDER BY rateN DESC, news_read DESC LIMIT 0,10
Конструкция (news_read-rate) as rateN определяет изменение между текущим просмотрам и на начало недели, и конечно сортируем по этому полю ORDER BY rateN DESC
Итого
title newsread rate rateN
нов2 28 20 8
нов1 16 10 6
нов3 404 400 4
нов4 802 800 2
Итак что получилось:
В понедельник мы заполняем поле rate и у нас нормальный рейтинг по всем новостям, при этом учитываем рейтинг только текущей недели и по нему сортируем.
Вроде бы все хорошо, но есть один нюанс: В момент обновления в понедельник рейтинга разница в рейтинге равна нулю и грубо говоря в итоге получаем, что рейтинг в этот день пляшет в зависимости от количества просмотров. Что тоже не очень хорошо.
Итого
title newsread rate rateN
нов4 802 802 0
нов3 404 404 0
нов2 28 28 0
нов1 16 16 0
Как найти способ убрать этот нюанс?
Не буду писать сюда свои размышления - как я пришёл к такому выводу, подведу лишь их итог, который оказался очень простым: Добавляем ещё одно поле - rate2 - для хранения данных с понедельника предыдущей недели.
Добавляем:
ALTER TABLE `dle_post` ADD `rate2` MEDIUMINT( 8 ) NOT NULL DEFAULT '0'
Теперь запрос на заполнение выглядет так:
UPDATE `dle_post` SET `arate2` = `arate`;
UPDATE `dle_post` SET `arate` = `news_read`;
Запрос на получение так:
SELECT (news_read-rate2) as rateN, (news_read-rate) as rateD, title FROM dle_post ORDER BY rateN DESC, news_read DESC LIMIT 0,10
(news_read-rate2) as rateN - Получаем разницу текущего показателя и показателя на понедельник предыдущей недели
(news_read-rate) as rateD - Получаем разницу текущего показателя и поазателя понедельник текущей недели
Итого
title newsread rate rate2 rateN rateD
нов4 818 818 800 18 0
нов1 28 28 10 18 0
нов2 36 36 20 16 0
нов3 406 406 400 6 0
В итоге получаем:
- 2 поля, по которым можно судить об изменениях просмотров новостей за текущую неделю и предыдущую.
- Адекватный рейтинг новостей с сортировкой по паказателю популярности за 2 недели
- Минимальную нагрузку
Собственно если мы хотим получить другой период, то просто запрос на обновление данных нужно запускать в течении нужного периода 2 раза.
К примеру если хотим за месяц - то запускам каждые 2 недели, если за неделю - то в среду после обеда (напомнило мелодию из детства...) и т. д.
Таким образом у меня в блоге построен топ популярных новостей.