# Discourse에서 'Top' 주제 계산하기

**URL:** https://meta.discourse.org/t/calculating-top-topics-in-discourse/240928
**Category:** Using Discourse
**Tags:** reference, interface
**Created:** [10월 4, 2022, 7:56오후 UTC](https://meta.discourse.org/t/calculating-top-topics-in-discourse/240928 "2022-10-04T19:56:38Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [10월 4, 2022, 7:56오후 UTC](https://meta.discourse.org/t/calculating-top-topics-in-discourse/240928/1 "2022-10-04T19:56:38Z")

</div>

> 🔖 “Top” 기준으로 필터링된 토픽이 Discourse에서 "Top Topics"로 결정되는 방식을 설명하는 참고 가이드입니다.
> 
> 🙋 필요한 사용자 권한: 모든 사용자

Discourse 사이트에는 사용자가 “Top” 기준으로 토픽을 정렬할 수 있는 기능이 있습니다. 이 가이드에서는 이러한 “Top” 토픽이 어떻게 계산되고 표시되는지 설명합니다.

## 요약

- 모든 “Top” 토픽에는 "Top Score"가 부여됩니다.
- 점수는 선택된 기간 내의 좋아요, 답변, 조회수를 기반으로 계산됩니다.
- 가장 높은 "Top Score"를 가진 토픽이 목록 상단에 표시됩니다.

## Top Score 계산

토픽의 "Top Score"는 다음 요소를 사용하여 계산됩니다:

1. 조회수
2. 첫 번째 게시물(원문)의 좋아요 수
3. 이후 게시물들의 좋아요 수
4. 답변 수

계산에는 관리자 설정 UI에서 볼 수 없지만 Rails 콘솔 또는 API를 통해 변경할 수 있는 숨겨진 사이트 설정 3개가 곱셈 인수로 사용됩니다:

- `top topics formula log views multiplier` (기본값: `2`)
- `top topics formula first post likes multiplier` (기본값: `0.5`)
- `top topics formula least likes per post multiplier` (기본값: `3`)

### 계산 단계

선택된 기간 내 각 토픽에 대해 다음 값을 합산하여 Top Score를 계산합니다:

1. 선택된 기간 내 각 토픽의 조회수(최소 1)의 로그 값에 `log views multiplier`를 곱한 값
2. 토픽의 원문 게시물 좋아요 수에 `first post likes multiplier`를 곱한 값
3. 다음 중 더 작은 값:
  - 게시물당 평균 좋아요 수 (토픽의 총 좋아요 수를 게시물 수로 나눈 값)
  - `least likes per post multiplier` 값

4. 기간 내 게시물이 10개 미만인 경우 다음 계산을 수행합니다:

```plaintext
0 - ((10 - 토픽 내 게시물 수) / 20) * 원문 게시물 좋아요 수

```

그렇지 않으면 `10`
5. 토픽의 게시물 수(최소 1)의 로그 값

## Top Topics 보기

아래 이미지에서 Discourse 사이트의 Top Topics 예시를 확인할 수 있습니다:

 ![Example of Top Topics on a site](https://global.discourse-cdn.com/meta/original/4X/9/e/f/9efd312a79536a9b8a38516160e8ef58c8b90c06.png)

## 추가 자료

더 자세한 기술적 내용은 다음 자료를 참고할 수 있습니다:

- Top 계산에 사용되는 Ruby 소스 코드: [discourse/app/models/top\_topic.rb at main · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/main/app/models/top_topic.rb#L157-L218)
- 각 토픽의 정확한 "Top Score"를 확인하기 위한 [Data Explorer](https://meta.discourse.org/t/discourse-data-explorer/32566) 쿼리:

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

```

---

_[View the full topic](https://meta.discourse.org/t/calculating-top-topics-in-discourse/240928)._
