这里是Reddit的热门算法:
cpdef double _hot(long ups, long downs, double date):
"""The hot formula. Should match the equivalent function in postgres."""
s = score(ups, downs)
order = log10(max(abs(s), 1))
if s > 0:
sign = 1
elif s < 0:
sign = -1
else:
sign = 0
seconds = date - 1134028003
return round(order + sign * seconds / 45000, 7)
我的大脑说,一个帖子的辣度应该根据每一个请求来计算,因为旧帖子的辣度分数应该很低。
我在MySql中实现了这个函数,但正如您可能猜到的那样,它很慢。非常慢,甚至还有索引。
然后,我想更新的热点领域的帖子,在每一次投票或否决的帖子。让我们假设,我们有一个帖子刚刚发布,并有100上票和1次投票,它的热度是78 (例子)。但它在三天内没有得到任何选票。3天后,一个新的职位出现,获得100票和1票,并有78分。如果我正在更新投票的热门评分,3天前的帖子和新的帖子将一起显示。但从理论上讲,这篇为期3天的帖子甚至不应该出现在头版上。
在这种情况下,最可行的方法是什么?
发布于 2013-01-24 11:18:04
我的大脑说,一个帖子的辣度应该根据每一个请求来计算,因为旧帖子的辣度分数应该很低。
你的大脑是错的。函数中的date
是最初发布的时间。该函数的值与计算时间无关,且在表决之间保持不变。记住这一点,你只需要在投票时更新它。您只需将数字存储在索引列上的数据库和查询中。性能问题消失了。
这也解决了你的第二个问题--今天发100张选票的帖子总是比昨天写的+100的帖子热。
发布于 2013-01-24 05:13:45
当您有长期运行的进程时,最好不要提出依赖于流程完成的请求。如果给用户最新的热度分数并不是最重要的,你可能会给用户一个相对接近的分数。
而不是对每个请求启动此计算,您应该有某种机制来触发一个后台进程,该进程可以提取所需的数据、计算热度并更新post的设置值。您的数据库希望类似于:
/* Other Post Data */
postViews - BIGINT // Number of actual post views
postViewsLastRun - BIGINT // Number of post views at last hotness job
lastViewed - DATETIME // Timestamp of the last viewing of the post
lastCalculated - DATETIME // Timestamp of the last hotness job
hostness - INT // Hotness rating to display to the user
根据您认为合适的内容,您可能希望在每个n
帖子查看数之后重新计算热度,或者您可能希望每小时计算一次。
对于前者,您将提取postViews
和postViewsLastRun
列,增加它,并根据您的帖子阈值检查它。如果postViewsLastRun
和postViews
之间的差异达到或超过了阈值,则需要使用某种作业调度器更新postViewsLastRun
派生的进程,以处理热评分的处理和更新。
对于后者,您需要运行一个计划好的进程,比如每小时运行一次。它将根据lastCalculated
列检查当前时间,以检查帖子是否在其阈值时间范围内被查看。假设满足了另一种计算的标准,它将派生出处理处理的作业,并继续检查数据库中其他帖子的相关数据。
现在,每当用户请求帖子的数据时,您就可以根据准确的标准给他们一个相对精确的热度等级,并且它不会因为长时间运行的计算而造成任何延迟。在您的示例中,您不会希望任何陈旧的信息出现,因为这会导致糟糕的用户体验,因此您需要使用定期运行的方法。
发布于 2013-01-24 04:59:30
在我看来(不是专家)是,你可以更新数据库中的热点在任何向上或否决,但为了区别新的和旧的职位,你可以应用某种等式,你保持在数据库中的热度。类似于:
hotnesss = hotness_from_up_and_down_votes_in_DB + (150 -(今日-后日期))+(15-(今日-最后一次投票日期))*10
这意味着,随着时间的推移,帖子会变得不那么火辣,超过150天的帖子就会开始产生负面的热度,而在过去15天里投票的帖子也会因此变得更热,而在没有投票的15天之后,它们就开始变得消极了。
如果你不想要负面的性感,你可以这样做:
hotnesss = hotness_from_up_and_down_votes_in_DB + (150 /((今日-后期日期)+ 1)) +(15/(今天-最后一次投票日期))*10
同样的事情,但随着时间的推移,你开始得到0,而不是负面。
注:+1 on“((今天-post_date)+1)”只是为了防止今天的帖子被150除以0
注意:您可以随意设置阈值( 150天和15天)。如果你想要一个更好的方程,你可以看看逻辑方程或指数方程。
希望能帮上忙。
https://softwareengineering.stackexchange.com/questions/184660
复制相似问题