这是关于 Discourse 中如何确定被“热门”过滤的主题为“热门主题”的参考指南。
所需用户级别:所有用户
Discourse 站点有一个允许用户按“热门”对主题进行排序的功能。本指南解释了这些“热门”主题的计算和显示方式。
摘要
- 所有“热门”主题都分配有“热门分数”。
- 该分数基于选定时间段内的点赞数、回复数和浏览量。
- “热门分数”最高的主题将显示在列表顶部。
热门分数计算
主题的“热门分数”使用以下因素计算:
- 浏览次数
- 第一个帖子的点赞数
- 后续帖子的点赞数
- 回复次数
计算使用三个站点设置作为乘数:
top topics formula log views multipliertop topics formula first post likes multipliertop topics formula least likes per post multiplier
计算步骤
通过将以下各项相加来计算每个主题的热门分数:
- 每个主题在选定期间的浏览次数乘以
log views multiplier。 - 主题原始帖子的点赞数乘以
first post likes multiplier。 - 以下两者中的较小值:
- 平均每帖点赞数(主题总点赞数除以帖子数)
least likes per post multiplier值
- 如果期间的帖子数少于 10 篇,则执行以下计算:
否则为0 - ((10 - 主题帖子数) / 20) * 原始帖子的点赞数-10。 - 主题的帖子数。
查看热门主题
您可以在下图的 Discourse 站点中看到热门主题的示例:
附加资源
有关更多技术细节,您可以参考:
- 热门计算的 Ruby 源代码:discourse/app/models/top_topic.rb at main · discourse/discourse · GitHub
- 此 Data Explorer 查询,用于查看每个主题的确切“热门分数”:
-- [params]
-- date :start_date = 26 apr 2020
-- date :end_date = 2 may 2020
-- double :log_views_multiplier = 2.0
-- double :first_post_likes_multiplier = 0.5
-- double :least_likes_per_post_multiplier = 3.0
WITH likes AS (
SELECT topic_id, SUM(like_count) AS count
FROM posts
WHERE created_at::date >= :start_date::date
AND created_at::date < :end_date::date
AND deleted_at IS NULL
AND NOT hidden
AND post_type = 1
GROUP BY topic_id
),
op_likes AS (
SELECT topic_id, like_count AS count
FROM posts
WHERE created_at::date >= :start_date::date
AND created_at::date < :end_date::date
AND post_number = 1
AND deleted_at IS NULL
AND NOT hidden
AND post_type = 1
),
posts AS (
SELECT topic_id, GREATEST(COUNT(*), 1) AS count
FROM posts
WHERE created_at::date >= :start_date::date
AND created_at::date < :end_date::date
AND deleted_at IS NULL
AND NOT hidden
AND post_type = 1
AND user_id <> 0
GROUP BY topic_id
),
views AS (
SELECT topic_id, COUNT(*) AS count
FROM topic_views
WHERE viewed_at::date >= :start_date::date
AND viewed_at::date < :end_date::date
GROUP BY topic_id
),
category_definition_topic_ids AS (
SELECT COALESCE(topic_id, 0) AS id FROM categories
),
top_topics AS(
SELECT
topics.id AS topic_id,
topics.title,
topics.user_id,
posts.count AS date_range_posts,
views.count AS date_range_views,
topics.views AS all_time_views,
topics.bumped_at,
(CASE
WHEN topics.created_at::date < :start_date::date
AND topics.created_at::date >= :end_date::date
THEN 0
ELSE log(GREATEST(views.count, 1)) * :log_views_multiplier +
op_likes.count * :first_post_likes_multiplier +
CASE WHEN likes.count > 0 AND posts.count > 0
THEN
LEAST(likes.count / posts.count, :least_likes_per_post_multiplier)
ELSE 0
END +
CASE WHEN topics.posts_count < 10 THEN
0 - ((10 - topics.posts_count) / 20) * op_likes.count
ELSE
10
END +
log(GREATEST(posts.count, 1))
END) AS score
FROM posts
INNER JOIN views ON posts.topic_id = views.topic_id
INNER JOIN likes ON posts.topic_id = likes.topic_id
INNER JOIN op_likes ON posts.topic_id = op_likes.topic_id
LEFT JOIN topics ON topics.id = posts.topic_id AND topics.deleted_at IS NULL
WHERE topics.deleted_at IS NULL
AND topics.visible
AND topics.archetype <> 'private_message'
AND NOT topics.archived
AND topics.id NOT IN (SELECT id FROM category_definition_topic_ids)
ORDER BY
score DESC,
topics.bumped_at DESC
)
SELECT * FROM top_topics WHERE score > 0

