1. Чего хотелось добиться?
Хотелось сделать, чтоб в колонке на видном месте появился список постов, которые могут показаться интересными моим драгоценным читателям. При этом в блоке должно происходить какое-то разнообразие - тупо 5 ссылок, одинаковых на всех страницах - это отстой и скука.
2. А чо это за посты?
Интересные в моем представлении - посты, которые:
- собрали дофига камментов
- и/или написаны не очень давно
- если юзер смотрит какой-то раздел - посты из этого же раздела интереснее
3. И как это работает?
Ну, я писал уже, что у меня тут не какой-нибудь Вордпресс, а своя вело-цмска. Чувак с вордпрессом включил бы какой-нибудь плагин - и лишился бы при этом удовольствия чо-то придумать и сделать своими руками. А вот не лишился :) Рассказываю любопытным про реализацию:
- Поскольку у меня тут не шибко дофига текстов, мы можем считать рейтинг "на лету" (тем более что есть "контексто-зависимый фактор" в виде текущего раздела
- То есть наша задача - добавить к SQL-запросу, показывающему посты, вычисляемое поле "rating" и отсортировать по нему результаты
- В тупом виде формула такая: "(кол-во комментов / возраст поста) * соответствие разделу"
- Но ее надо настроить, расставив коэффициенты, чтоб было красиво.
- Возраст я решил считать, беря квадратный корень от кол-ва секунд, прошедших с момента написания поста:
SQRT(UNIX_TIMESTAMP(NOW()) - T.creation_date)
- Если на это делить кол-во комментов "как есть", вверх полезут старые посты с большим кол-вом комментов. Поигравшись с результатами, возвел кол-во комментов в степень 0.5:
POW(T.count_comments,0.5)
- Добавляем фактор раздела, если он есть. Мне понравилось умножение на 2.5:
IF(S.parent = %section_id, 2.5, 1)
- Итоговый запрос получается какой-то такой:
SELECT T.*,
POW(T.count_comments,0.5) *
SQRT(UNIX_TIMESTAMP(NOW()) - T.creation_date) *
IF(S.parent = %section_id, 2.5, 1) as rating
FROM posts T
ORDER BY rating DESC
LIMIT 20
- Остается добавить выбор 5 случайных постов из полученных 20 с наибольшим рейтингом. Любой пыхарь, используя shuffle() и array_slice(), сделает это за полторы минуты :)
- Для понта полученное значение рейтинга можно вывести на экран. Оно нифига не значит, но внушает. Чтоб оно было читаемее, сделаем round($rating*10000, 2)
- Для красоты еще раз сортируем отобранные 5 случайных записей по рейтингу. Я это сделал прямо в XSL-шаблоне.
- Остается прикрутить стили :)
Это алгоритм в общем виде, если кто захочет реализовать у себя - обращайтесь, чо, подскажу :)
4. Можно ли улучшить?
Ага, наверняка.
Во-первых, можно считать кол-во просмотров и использовать в формуле (желательно - нормализовав на возраст поста).
Во-вторых, аналогично разделу можно использовать теги, типа что при просмотре поста про синхронный перевод в Киеве например, справа появлялось чо-то еще про Киев. Но это усложняет и утяжеляет запрос (т.к. теги хранятся мэни-ту-мэни), к тому же уже реализовано в блоке "что еще почитать" в конце поста :)
В-третьих, конечно, по уму этот рейтинг надо хранить и пересчитывать типа раз в сутки.