Calculando los temas "Top" en Discourse

:bookmark: Esta es una guía de referencia que explica cómo los temas filtrados por “Top” se determinan como “Temas Principales” en Discourse.

:person_raising_hand: Nivel de usuario requerido: Todos los usuarios

Los sitios de Discourse tienen una función que permite a los usuarios ordenar los temas por “Top”. Esta guía explica cómo se calculan y muestran estos temas “Top”.

Resumen

  • A todos los temas “Top” se les asigna una “Puntuación Top”.
  • La puntuación se basa en “me gusta”, respuestas y vistas dentro de un período de tiempo seleccionado.
  • Los temas con la “Puntuación Top” más alta aparecen en la parte superior de la lista.

Cálculo de la Puntuación Top

La “Puntuación Top” de un tema se calcula utilizando los siguientes factores:

  1. Número de vistas
  2. “Me gusta” en la primera publicación
  3. “Me gusta” en publicaciones posteriores
  4. Número de respuestas

El cálculo utiliza tres configuraciones del sitio como multiplicadores:

Pasos del cálculo

Calcula una puntuación principal para cada tema sumando lo siguiente:

  1. El número de vistas de cada tema en el período seleccionado multiplicado por el log views multiplier.
  2. El número de “me gusta” en la publicación original del tema multiplicado por el first post likes multiplier.
  3. El menor de:
    • El promedio de “me gusta” por publicación (total de “me gusta” en el tema dividido por el número de publicaciones).
    • El valor del least likes per post multiplier.
  4. Si el período tiene menos de 10 publicaciones, realiza el siguiente cálculo:
    0 - ((10 - número de publicaciones en el tema) / 20) * número de "me gusta" en la publicación original
    
    De lo contrario, -10.
  5. El número de publicaciones en el tema.

Visualización de Temas Principales

Puedes ver un ejemplo de Temas Principales en un sitio de Discourse en la siguiente imagen:

Recursos adicionales

Para obtener más detalles técnicos, puedes consultar:

  • El código fuente de Ruby para el cálculo principal: discourse/app/models/top_topic.rb at main · discourse/discourse · GitHub
  • Esta consulta de Data Explorer para ver la “Puntuación Top” exacta de cada tema:
    -- [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 Me gusta

¿Es posible incluir ‘votos’ en este cálculo?

Estas ahora están ocultas, por lo que no las verás en la configuración del sitio