FEATURE: top topics all time

tweak top algorithm (we will continue next week)
This commit is contained in:
Sam 2015-03-06 18:00:29 +11:00
parent db7a225df7
commit 2a586d59e9
4 changed files with 65 additions and 8 deletions

View file

@ -21,6 +21,8 @@ export default Ember.Object.extend({
title = "this_month"; title = "this_month";
} else if (id === "daily") { } else if (id === "daily") {
title = "today"; title = "today";
} else if (id === "all") {
title = "all";
} }
this.set('title', I18n.t("filters.top." + title)); this.set('title', I18n.t("filters.top." + title));

View file

@ -14,13 +14,15 @@ class TopTopic < ActiveRecord::Base
# We don't have to refresh these as often # We don't have to refresh these as often
def self.refresh_older! def self.refresh_older!
older_periods = periods - [:daily] older_periods = periods - [:daily,:all]
transaction do transaction do
older_periods.each do |period| older_periods.each do |period|
update_counts_and_compute_scores_for(period) update_counts_and_compute_scores_for(period)
end end
end end
compute_top_score_for(:all)
end end
def self.refresh! def self.refresh!
@ -30,11 +32,11 @@ class TopTopic < ActiveRecord::Base
def self.periods def self.periods
@@periods ||= [:yearly, :monthly, :weekly, :daily].freeze @@periods ||= [:all, :yearly, :monthly, :weekly, :daily].freeze
end end
def self.sort_orders def self.sort_orders
@@sort_orders ||= [:posts, :views, :likes].freeze @@sort_orders ||= [:posts, :views, :likes, :op_likes].freeze
end end
def self.update_counts_and_compute_scores_for(period) def self.update_counts_and_compute_scores_for(period)
@ -103,7 +105,7 @@ class TopTopic < ActiveRecord::Base
end end
def self.update_likes_count_for(period) def self.update_likes_count_for(period)
sql = "SELECT topic_id, GREATEST(SUM(like_count), 1) AS count sql = "SELECT topic_id, SUM(like_count) AS count
FROM posts FROM posts
WHERE created_at >= :from WHERE created_at >= :from
AND deleted_at IS NULL AND deleted_at IS NULL
@ -114,16 +116,58 @@ class TopTopic < ActiveRecord::Base
update_top_topics(period, "likes", sql) update_top_topics(period, "likes", sql)
end end
def self.update_op_likes_count_for(period)
sql = "SELECT topic_id, like_count AS count
FROM posts
WHERE created_at >= :from
AND post_number = 1
AND deleted_at IS NULL
AND NOT hidden
AND post_type = #{Post.types[:regular]}"
update_top_topics(period, "op_likes", sql)
end
def self.compute_top_score_for(period) def self.compute_top_score_for(period)
if period == :all
top_topics = "(
SELECT t.like_count all_likes_count,
t.id topic_id,
t.posts_count all_posts_count,
p.like_count all_op_likes_count,
t.views all_views_count
FROM topics t
JOIN posts p ON p.topic_id = t.id AND p.post_number = 1
) as top_topics"
time_filter = "false"
else
top_topics = "top_topics"
time_filter = "topics.created_at < :from"
end
sql = <<-SQL sql = <<-SQL
WITH top AS ( WITH top AS (
SELECT CASE SELECT CASE
WHEN topics.created_at < :from THEN 0 WHEN #{time_filter} THEN 0
ELSE log(greatest(#{period}_views_count, 1)) + #{period}_likes_count * 2 + #{period}_posts_count * 2 ELSE log(GREATEST(#{period}_views_count, 1)) * 2 +
#{period}_op_likes_count * 0.5 +
CASE WHEN #{period}_likes_count > 0 AND #{period}_posts_count > 0
THEN
LEAST(#{period}_likes_count / #{period}_posts_count, 3)
ELSE 0
END +
CASE WHEN topics.posts_count < 10 THEN
0 - ((10 - topics.posts_count) / 20) * #{period}_op_likes_count
ELSE
10
END +
log(GREATEST(#{period}_posts_count, 1))
END AS score, END AS score,
topic_id topic_id
FROM top_topics FROM #{top_topics}
LEFT JOIN topics ON topics.id = top_topics.topic_id LEFT JOIN topics ON topics.id = top_topics.topic_id AND
topics.deleted_at IS NULL
) )
UPDATE top_topics UPDATE top_topics
SET #{period}_score = top.score SET #{period}_score = top.score

View file

@ -1494,6 +1494,7 @@ en:
title: "Top Weekly" title: "Top Weekly"
daily: daily:
title: "Top Daily" title: "Top Daily"
all: "All Time"
this_year: "This year" this_year: "This year"
this_month: "This month" this_month: "This month"
this_week: "This week" this_week: "This week"

View file

@ -0,0 +1,10 @@
class AddAllTimeAndOpLikesToTopTopics < ActiveRecord::Migration
def change
add_column :top_topics, :all_score, :float, default: 0
[:daily, :weekly, :monthly, :yearly].each do |period|
column = "#{period}_op_likes_count"
add_column :top_topics, column, :integer, default: 0, null: false
add_index :top_topics, [column]
end
end
end