From 2a586d59e9eefd059ea9b344031752bacc4cf4aa Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 6 Mar 2015 18:00:29 +1100 Subject: [PATCH] FEATURE: top topics all time tweak top algorithm (we will continue next week) --- .../discourse/models/top-period.js.es6 | 2 + app/models/top_topic.rb | 60 ++++++++++++++++--- config/locales/client.en.yml | 1 + ...add_all_time_and_op_likes_to_top_topics.rb | 10 ++++ 4 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb diff --git a/app/assets/javascripts/discourse/models/top-period.js.es6 b/app/assets/javascripts/discourse/models/top-period.js.es6 index 9aef0fcda..ad4323b68 100644 --- a/app/assets/javascripts/discourse/models/top-period.js.es6 +++ b/app/assets/javascripts/discourse/models/top-period.js.es6 @@ -21,6 +21,8 @@ export default Ember.Object.extend({ title = "this_month"; } else if (id === "daily") { title = "today"; + } else if (id === "all") { + title = "all"; } this.set('title', I18n.t("filters.top." + title)); diff --git a/app/models/top_topic.rb b/app/models/top_topic.rb index 9905a7b32..ca7290a67 100644 --- a/app/models/top_topic.rb +++ b/app/models/top_topic.rb @@ -14,13 +14,15 @@ class TopTopic < ActiveRecord::Base # We don't have to refresh these as often def self.refresh_older! - older_periods = periods - [:daily] + older_periods = periods - [:daily,:all] transaction do older_periods.each do |period| update_counts_and_compute_scores_for(period) end end + + compute_top_score_for(:all) end def self.refresh! @@ -30,11 +32,11 @@ class TopTopic < ActiveRecord::Base def self.periods - @@periods ||= [:yearly, :monthly, :weekly, :daily].freeze + @@periods ||= [:all, :yearly, :monthly, :weekly, :daily].freeze end def self.sort_orders - @@sort_orders ||= [:posts, :views, :likes].freeze + @@sort_orders ||= [:posts, :views, :likes, :op_likes].freeze end def self.update_counts_and_compute_scores_for(period) @@ -103,7 +105,7 @@ class TopTopic < ActiveRecord::Base end 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 WHERE created_at >= :from AND deleted_at IS NULL @@ -114,16 +116,58 @@ class TopTopic < ActiveRecord::Base update_top_topics(period, "likes", sql) 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) + + 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 WITH top AS ( SELECT CASE - WHEN topics.created_at < :from THEN 0 - ELSE log(greatest(#{period}_views_count, 1)) + #{period}_likes_count * 2 + #{period}_posts_count * 2 + WHEN #{time_filter} THEN 0 + 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, topic_id - FROM top_topics - LEFT JOIN topics ON topics.id = top_topics.topic_id + FROM #{top_topics} + LEFT JOIN topics ON topics.id = top_topics.topic_id AND + topics.deleted_at IS NULL ) UPDATE top_topics SET #{period}_score = top.score diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index db41b8a47..1007f3410 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1494,6 +1494,7 @@ en: title: "Top Weekly" daily: title: "Top Daily" + all: "All Time" this_year: "This year" this_month: "This month" this_week: "This week" diff --git a/db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb b/db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb new file mode 100644 index 000000000..36bc6de65 --- /dev/null +++ b/db/migrate/20150306050437_add_all_time_and_op_likes_to_top_topics.rb @@ -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