Как внедрить пользовательскую рейтинговую систему (с уместностью даты) - PullRequest
2 голосов
/ 15 декабря 2008

Я работаю над сайтом, похожим на digg, в отношении того, что пользователи могут отправлять "истории".

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

Вот часть алгоритма (по сути, наиболее важная):

y = day number 
sy = number of adds on day y

∑ y[1:10]  sy / y

Таким образом, по сути, рассчитайте количество «похожих добавок» в указанный день и разделите на количество секунд с момента публикации контента. Делайте это в течение последних 10 дней (как пример).

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

Единственный способ реализовать это - рассчитать количество добавлений за последние 10 дней для каждого представленного элемента, который будет длиться вечно. (поэтому команда sql с группировкой по дате выполнялась 10 раз за последние 10 дней - очевидно, этот метод отстой).

Даже если я сохраню таблицу, которую обновляю раз в день (и запускаю вышеупомянутый sql в фоновом режиме), она все равно будет невероятно медленной, когда база данных станет большой. Кроме того, рейтинг будет «устаревшим», поскольку он не является живым (например, «новости» из последних новостей никогда не достигнут вершины).

Кто-нибудь знает, как это сделать?

Ответы [ 3 ]

2 голосов
/ 15 декабря 2008

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

1 голос
/ 18 мая 2010

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

const float WeightFactor = 0.70; //for example
float PreviousAverage = GetPreviousAverage();
float CurrentValue = GetVoteCountToday();

float NewAverage = (WeightFactor * CurrentValue) + ( (1-WeightFactor) * PreviousAverage);

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

0 голосов
/ 15 декабря 2008

Не было бы необходимости выполнять SQL 10 раз, чтобы получить результат, вы могли бы получить его за одно выполнение, например:

select sum(dayval)
from
( select count(*) / (current_date-day+1) dayval
  from votes
  where story_id = 123
  and day >= current_date - 9
  group by (current_date-day+1)
)

(Фактический код зависит от используемой СУБД).

Я не утверждаю, что это будет хорошо, хотя!

Возможно, компромисс: вычислить и сохранить значение «начала дня» в ежедневном пакетном процессе, но затем добавить 1 к сохраненному значению для каждого голоса, полученного в течение дня?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...