Calculer les sujets "Top" dans Discourse

:bookmark: Ce guide de référence explique comment les sujets filtrés par « Top » sont déterminés comme étant des « Sujets Populaires » 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 “j’aime”, les réponses et les vues au cours d’une période sélectionnée
  • Les sujets avec le « Score Top » le plus élevé apparaissent en haut de la liste

Calcul du Score Top

Le « Score Top » d’un sujet est calculé en utilisant les facteurs suivants :

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

Le calcul utilise trois paramètres de site masqués comme multiplicateurs (ceux-ci ne sont pas visibles dans l’interface des paramètres d’administration, mais peuvent être modifiés via la console Rails ou l’API) :

  • top topics formula log views multiplier (par défaut : 2)
  • top topics formula first post likes multiplier (par défaut : 0.5)
  • top topics formula least likes per post multiplier (par défaut : 3)

Étapes du calcul

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

  1. Le logarithme du nombre de vues (minimum 1) pour chaque sujet dans la période sélectionnée, multiplié par le log views multiplier
  2. Le nombre de “j’aime” sur le message original du sujet multiplié par le first post likes multiplier
  3. Le plus petit entre :
    • La moyenne des “j’aime” par message (total des “j’aime” sur le sujet divisé par le nombre de messages)
    • La valeur du least likes per post multiplier
  4. Si la période compte moins de 10 messages, effectuez le calcul suivant :
    0 - ((10 - nombre de messages dans le sujet) / 20) * nombre de "j'aime" sur le message original
    
    Sinon, 10
  5. Le logarithme du nombre de messages (minimum 1) sur le sujet

Visualisation des Sujets Populaires

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

Ressources supplémentaires

Pour plus de détails techniques, vous pouvez consulter :

-- [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