# 如何使用插件自定义热门话题得分算法？

**URL:** https://meta.discourse.org/t/how-do-you-customize-hot-topic-score-algorithm-with-a-plugin/396003
**Category:** Development
**Created:** [2026年二月13日 09:13 UTC](https://meta.discourse.org/t/how-do-you-customize-hot-topic-score-algorithm-with-a-plugin/396003 "2026-02-13T09:13:43Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![fangjue](https://avatars.discourse-cdn.com/v4/letter/f/b5ac83/32.png) [@fangjue](https://meta.discourse.org/u/fangjue)
#### Post date: [2026年二月13日 09:13 UTC](https://meta.discourse.org/t/how-do-you-customize-hot-topic-score-algorithm-with-a-plugin/396003/1 "2026-02-13T09:13:44Z")

</div>

内置的 [热门排序](https://meta.discourse.org/t/discover-popular-conversations-in-your-community-with-hot-topic-sorting/296747) [算法](https://github.com/discourse/discourse/blob/main/app/models/topic_hot_score.rb) 非常简单，可能不适用于不同的使用场景。根据我对 Discourse 代码库的基本理解，目前没有面向用户的站点设置或适当的插件注入点来定制热门排序算法。有一个 `topic_hot_scores_updated` 事件，但它在分数更新后才被调用，这可以用于_通知_，但不能_覆盖_内置的热门分数。有两个站点设置 `hot_topics_gravity` 和 `hot_topics_recent_days`，但它们被设置为 `hidden: true` 并且在管理员界面中不可见。

我们正在考虑编写一个插件来替换内置的热门分数算法。从与未来升级 Discourse 的兼容性和便捷性来看，哪种方法会更好？我列出了一些想法如下：

- Monkey-patch `TopicHotScore` 并根据我们的自定义算法更新数据库。
- 创建一个单独的表来存储热门分数，并运行一个单独的后台作业来更新它们。为我们的自定义热门话题列表添加另一个路由（而不是 /hot）。
- 或者也许 Discourse 代码库可以改进以支持这种用例？

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [2026年二月13日 09:58 UTC](https://meta.discourse.org/t/how-do-you-customize-hot-topic-score-algorithm-with-a-plugin/396003/2 "2026-02-13T09:58:34Z")

</div>

> [@fangjue](#):
>
> 猴子补丁 `TopicHotScore` 并根据我们的自定义算法更新数据库。

最简单，但根据您想做的事情，可能会有所限制。

> [@fangjue](#):
>
> 创建一个单独的表来存储主题热门分数，并运行一个单独的后台作业来更新它们。添加另一个路由（而不是 /hot）用于我们的自定义热门主题列表。

可行，但更复杂。请查看 [TopicQuery 如何实现列表](https://github.com/discourse/discourse/blob/7691be669a6a54175ee43c81d110b993e6de3a69/lib/topic_query.rb#L196-L395)

特别是

```plaintext
  def list_hot
    create_list(:hot, unordered: true, prioritize_pinned: true) do |topics|
      topics = remove_muted(topics, user, options)
      topics.joins("JOIN topic_hot_scores on topics.id = topic_hot_scores.topic_id").order(
        "topic_hot_scores.score DESC",
      )
    end
  end

```

您可以相对容易地添加一个额外的列表，尽管您需要考虑相当多的变动部分。我在我的 ‘[homepage-filter](https://github.com/communiteq/discourse-homepage-filter/blob/main/plugin.rb)’ 插件中这样做了，那可能是一个很好的起点。
