Реализация трендовых тем

В настоящее время я нахожусь на пути реализации Trending Topics в моем приложении Rails.

Что у меня сейчас есть, так это:

Каждый пост имеет topic атрибут от 2 до 3 слов, описывающий его тему.

Затем я получаю лучшие посты по количеству просмотров (у меня также есть лайки и избранное, но пока я использую просто просмотры):

def trending_topics
  Post.order("COALESCE(impressions_count, 0) DESC").limit(200)
end

И тогда я просто выбираю только уникальные темы и показываю их несколько:

  <% trending_topics.select(:topic).map(&:topic).uniq.take(10).each do |topic| %>
      <li><%= topic %></li>
  <% end %>

Мои вопросы:

  1. Есть ли способ получить наиболее часто появляющиеся :topic, ранжировать их, и выбрать сливки урожая тех?
  2. Это устойчивый способ отслеживать популярные темы? Если нет, есть ли способ сделать его более эффективным?
  3. Есть ли лучший способ реализовать функцию, которая ищет наиболее популярные и частые :topic атрибуты в постах?

2 ответа

Решение

Чтобы ответить на ваши вопросы:

(1) Да, вы можете получить хэш с частотой каждого :topic вот так:

array = trending_topics.select(:topic).map(&:topic)
freq = array.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
# => {'topic1'=>3, 'topic2'=>3, 'topic3'=>1, ...}

(2) Это является "устойчивым" в том смысле, что его сложность не возрастает по мере увеличения количества вводимых вами постов / тем (поскольку вы по-прежнему отбираете 200 лучших постов, хотя получение "топ 200" займет немного больше времени вычислений по мере роста количества постов).

(3) Я думаю, что impressions_count было бы не очень хорошим способом отслеживать то, что в тренде, так как для меня impressions_count имеет общее количество показов, в то время как вы хотите некоторый временной аспект (например, impressions_this_week).

Так что один из способов сделать это было бы ввести impressions_this_week столбец, который обновляется через равные промежутки времени. Тогда вы можете выбрать на основе этого.

Другим способом было бы написать метод, который использует общий impressions_count вместе с created_at или же updated_at отметка времени, чтобы вычислить, насколько "горячим" является пост. Вы можете сделать это с помощью простой функции затухания, а затем настраивать константы этой функции до тех пор, пока не получите нужный затухание. Здесь есть нечто похожее на эту концепцию: http://blog.notdot.net/2009/12/Most-popular-metrics-in-App-Engine. После того, как вы написали этот метод, вы можете просто отсортировать его по выводу.

Если вам нужно что-то более сложное, чем ваш текущий алгоритм ранжирования, вам, вероятно, стоит взглянуть на то, как такие сайты, как reddit и hackernew s, решают эту проблему. Это довольно сложно, но вы должны быть в состоянии найти реализацию каждого алгоритма в Ruby, если вы гуглите его.

Другие вопросы по тегам