Calcul des sujets "Top" dans Discourse

:bookmark: Ce guide de référence explique comment les sujets filtrés par « Top » sont déterminés comme « Sujets Top » dans Discourse.

:person_raising_hand: Niveau d’utilisateur requis : Tous les utilisateurs

Les sites Discourse disposent d’une fonctionnalité qui permet aux utilisateurs de trier les sujets par « Top ». Ce guide explique comment ces sujets « Top » sont calculés et affichés.

Résumé

  • Tous les sujets « Top » se voient attribuer un « Score Top ».
  • Le score est basé sur les mentions « J’aime », les réponses et les vues sur une période sélectionnée.
  • Les sujets ayant le « Score Top » le plus élevé apparaissent en haut de la liste.

Calcul du Score Top

Le « Score Top » d’un sujet est calculé à l’aide des facteurs suivants :

  1. Nombre de vues
  2. Mentions « J’aime » sur le premier message
  3. Mentions « J’aime » sur les messages suivants
  4. Nombre de réponses

Le calcul utilise trois paramètres du site comme multiplicateurs :

Étapes de calcul

Calculez un score top pour chaque sujet en additionnant les éléments suivants :

  1. Le nombre de vues pour chaque sujet dans la période sélectionnée, multiplié par le log views multiplier.
  2. Le nombre de mentions « J’aime » sur le message d’origine du sujet, multiplié par le first post likes multiplier.
  3. Le plus petit des éléments suivants :
    • Les mentions « J’aime » moyennes par message (total des mentions « J’aime » sur le sujet divisé par le nombre de messages).
    • La valeur least likes per post multiplier.
  4. Si la période contient moins de 10 messages, effectuez le calcul suivant :
    0 - ((10 - nombre de messages dans le sujet) / 20) * nombre de mentions « J'aime » sur le message d'origine
    
    Sinon, -10.
  5. Le nombre de messages du sujet.

Affichage des sujets Top

Vous pouvez voir un exemple de sujets Top sur un site Discourse dans l’image ci-dessous :

Ressources supplémentaires

Pour plus de détails techniques, vous pouvez vous référer à :

  • Le code source Ruby pour le calcul du score top : discourse/app/models/top_topic.rb at main · discourse/discourse · GitHub
  • Cette requête Data Explorer pour voir le « Score Top » exact pour chaque sujet :
    -- [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 « J'aime »

Est-il possible d’inclure des « votes » dans ce calcul ?

Ceux-ci sont maintenant masqués, vous ne les verrez donc pas dans les paramètres du site