Discourseの「トップ」トピックの計算

:bookmark: これは、Discourse で「トップ」によってフィルタリングされたトピックがどのように「トップ トピック」として決定されるかを説明するリファレンス ガイドです。

:person_raising_hand: 必要なユーザーレベル: 全ユーザー

Discourse サイトには、ユーザーがトピックを「トップ」で並べ替えることができる機能があります。このガイドでは、「トップ」トピックがどのように計算および表示されるかを説明します。

要約

  • すべての「トップ」トピックには「トップ スコア」が割り当てられます。
  • スコアは、選択した期間内のいいね、返信、および表示回数に基づいています。
  • 「トップ スコア」が最も高いトピックがリストの上位に表示されます。

トップ スコアの計算

トピックの「トップ スコア」は、次の要因を使用して計算されます。

  1. 表示回数
  2. 最初の投稿へのいいね
  3. 後続の投稿へのいいね
  4. 返信数

計算では、3 つのサイト設定が乗数として使用されます。

計算手順

次の合計を計算して、各トピックのトップ スコアを計算します。

  1. 選択した期間の各トピックの表示回数に log views multiplier を掛けたもの
  2. トピックの元の投稿へのいいね数に first post likes multiplier を掛けたもの
  3. 次のいずれか小さい方:
    • 投稿あたりの平均いいね数 (トピックの合計いいね数 / 投稿数)
    • least likes per post multiplier の値
  4. 期間の投稿数が 10 未満の場合は、次の計算を実行します。
    0 - ((10 - トピックの投稿数) / 20) * 元の投稿へのいいね数
    
    それ以外の場合は -10
  5. トピックの投稿数

トップ トピックの表示

下の画像は、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
    
「いいね!」 12

この計算に「票」を含めることは可能ですか?

これらは非表示になったため、サイト設定では表示されなくなりました。