您提到在 SQL 查询中执行此操作,因此我将在其中提供示例。
如果你有一个 table/view Pages
,像这样
Pages
-----
page_id:int
views:int - indexed
comments:int - indexed
然后你可以通过写作来订购它们
SELECT * FROM Pages
ORDER BY
(0.3+LOG10(10+views)/LOG10(10+(SELECT MAX(views) FROM Pages))) +
(0.7+LOG10(10+comments)/LOG10(10+(SELECT MAX(comments) FROM Pages)))
我故意在观点和评论之间选择了不相等的权重。与视图/评论保持同等权重可能出现的一个问题是,排名变成了一个自我实现的预言——一个页面被返回到列表的顶部,所以它被更频繁地访问,从而获得更多的分数,所以它是显示在列表的末尾,并且访问频率更高,获得的积分也更多。... 对评论给予更多重视反映了这些需要真正的努力并表现出真正的兴趣。
上述公式将根据历史统计数据为您提供排名。因此,上周积累的浏览量/评论数量与去年积累的另一篇文章相同的文章将被给予相同的优先级。重复这个公式可能是有意义的,每次都指定一个日期范围,并偏爱具有较高活动的页面,例如
0.3*(score for views/comments today) - live data
0.3*(score for views/comments in the last week)
0.25*(score for views/comments in the last month)
0.15*(score for all views/comments, all time)
这将确保“热门”页面的优先级高于最近没有太多动作的类似评分页面。除了今天的分数之外的所有值都可以通过预定的存储过程保存在表中,这样数据库就不必聚合许多评论/查看统计信息。只有今天的统计数据是“实时”计算的。更进一步,排名公式本身可以通过每天运行的存储过程计算和存储历史数据。
编辑:要获得从 0.1 到 1.0 的严格范围,您可以像这样设计公式。但我强调 - 这只会增加开销并且是不必要的 - 优先级的绝对值并不重要 - 只有它们与其他 url 的相对值。搜索引擎使用这些来回答问题,URL A 是否比 URL B 更重要/相关?它通过比较它们的优先级——哪个是最大的——而不是它们的绝对值来做到这一点。
// 未标准化 - x 是某个页面 id un(x) = 0.3*log(views(x)+10)/log(10+maxViews()) + 0.7*log(comments(x)+10)/log(10 +maxComments()) // 原始公式(现在是伪代码)
最大值将为 1.0,最小值将从 1.0 开始,并随着更多视图/评论的出现而向下移动。
我们将un(0)定义为最小值,即(上式中views(x)和comments(x)均为0)
为了得到一个从 0.1 到 1.0 的归一化公式,然后计算 n(x),即页面的归一化优先级x
(1.0-un(x)) * (un(0)-0.1)
n(x) = un(x) - ------------------------- when un(0) != 1.0
1.0-un(0)
= 0.1 otherwise.