Алгоритм популярности - PullRequest
12 голосов
/ 22 июня 2009

Я делаю Digg-подобный веб-сайт, который будет иметь домашнюю страницу с разными категориями. Я хочу отобразить самые популярные материалы.

Наша рейтинговая система просто «нравится», например «Мне нравится это» и еще много чего. Мы в основном хотим отображать материалы с наибольшим количеством лайков за раз. Мы хотим иметь три категории: абсолютная популярность, последняя неделя и последний день.

Кто-нибудь знает способ помочь? Я понятия не имею, как сделать это и сделать это эффективным. Я думал, что мы могли бы использовать какую-то работу cron для запуска каждые 10 минут и подсчета количества лайков за последние 10 минут ... но мне сказали, что это довольно неэффективно?

Помощь

Спасибо!

Ответы [ 5 ]

9 голосов
/ 22 июня 2009

Обычно сайты, подобные Digg и Reddit, идут по дате подачи, а не по времени голосования. Таким образом, все, что нужно, - это простой запрос SQL, чтобы найти самые популярные материалы за период времени X. Вот псевдопросмотр, чтобы найти 10 самых популярных ссылок за последние 24 часа, используя этот метод:

select * from submissions
 where (current_time - post_time) < 86400
 order by score desc limit 10

По сути, этот запрос говорит, что нужно найти все отправления, в которых количество секунд между моментом публикации и временем публикации меньше 86400, что в UNIX составляет 24 часа.

Если вы действительно хотите измерить популярность за интервал времени X, вам нужно будет сохранить запись и время для каждого голосования в другой таблице:

create table votes (
 post foreign key references submissions(id),
 time datetime,
 vote integer); -- +1 for upvote, -1 for downvote

Затем вы можете создать список самых популярных сообщений между X и Y разами так:

select sum(vote), post from votes
 where X < time and time < Y
 group by post
 order by sum(vote) desc limit 10;

Отсюда вы просто переходите, пропускаете и выполняете внутреннее соединение, не привязывая данные поста к возвращенным идентификаторам.

3 голосов
/ 22 июня 2009

У вас есть достойная установка БД? Можем ли мы услышать о ваших CREATE TABLE деталях и индексах? Предполагая разумную настройку, БД должна быть в состоянии вывести нужные вам значения достаточно быстро, чтобы удовлетворить ваши потребности! Например (сеть индексов и ключей, которые в некоторой степени зависят от того, какой механизм БД вы используете), для двух таблиц:

CREATE TABLE submissions (subid INT, when DATETIME, etc etc)
CREATE TABLE likes (subid INT, when DATETIME, etc etc)

Вы можете получить топ-33 за все время популярных представлений как

SELECT *, COUNT(likes.subid) AS score
FROM submissions
JOIN likes USING(subid)
GROUP BY submissions.subid
ORDER BY COUNT(likes.subid) DESC
LIMIT 33

и проголосовавшие за определенный промежуток времени как

SELECT *, COUNT(likes.subid) AS score
FROM submissions
JOIN likes USING(subid)
WHERE likes.when BETWEEN initial_time AND final_time
GROUP BY submissions.subid
ORDER BY COUNT(likes.subid) DESC
LIMIT 33

Если бы вы сохраняли «голоса» (положительные или отрицательные) в likes, вместо того чтобы просто считать каждую запись там как +1, вы могли бы просто использовать SUM(likes.vote) вместо COUNT s.

0 голосов
/ 23 июня 2009

Запросы, в которых порядок является некоторой функцией текущего времени, могут стать реальными проблемами производительности. Ситуация становится намного проще, если вы можете собирать данные по календарному времени и обновлять оценки для каждого сегмента по мере того, как люди голосуют.

0 голосов
/ 22 июня 2009

Для стабильных списков, таких как alltime, lastweek, потому что они не должны меняться очень быстро, поэтому я думаю, что вы должны сохранить список в своем кэше со сроком действия около 1 дня или более.

Если вы беспокоитесь о правильном подсчете в реальном времени, вы можете проверять каждый просмотр страницы, сравнивая страницу с самой низкой страницей в кэше.

Все, что вам нужно сделать, это позаботиться о синхронизации между кешем и реальной базой данных.

thethanghn

0 голосов
/ 22 июня 2009

Чтобы ответить никому_, я бы предложил вам прочитать документацию (если вы, конечно, используете MySQL).

...