2013-02-05 14:16:51 -05:00
class ScoreCalculator
2013-02-25 19:42:20 +03:00
def self . default_score_weights
2013-02-05 14:16:51 -05:00
{
reply_count : 5 ,
2013-05-27 12:45:10 -04:00
like_score : 15 ,
2013-02-05 14:16:51 -05:00
incoming_link_count : 5 ,
bookmark_count : 2 ,
avg_time : 0 . 05 ,
reads : 0 . 2
}
end
def initialize ( weightings = nil )
@weightings = weightings || ScoreCalculator . default_score_weights
end
# Calculate the score for all posts based on the weightings
2014-02-27 11:45:20 +11:00
def calculate ( min_topic_age = nil )
2013-02-05 14:16:51 -05:00
2014-02-27 11:45:20 +11:00
update_posts_score ( min_topic_age )
2013-02-05 14:16:51 -05:00
2014-02-27 11:45:20 +11:00
update_posts_rank ( min_topic_age )
update_topics_rank ( min_topic_age )
update_topics_percent_rank ( min_topic_age )
end
private
def update_posts_score ( min_topic_age )
components = [ ]
@weightings . keys . each { | k | components << " COALESCE( #{ k . to_s } , 0) * : #{ k . to_s } " }
components = components . join ( " + " )
builder = SqlBuilder . new (
" UPDATE posts SET score = x.score
FROM ( SELECT id , #{components} as score FROM posts) AS x
/ *where* / "
)
builder . where ( " x.id = posts.id
AND ( posts . score IS NULL OR x . score < > posts . score ) " , @weightings)
filter_topics ( builder , min_topic_age )
builder . exec
end
def update_posts_rank ( min_topic_age )
builder = SqlBuilder . new ( " UPDATE posts SET percent_rank = x.percent_rank
2013-03-22 15:43:57 -04:00
FROM ( SELECT id , percent_rank ( )
OVER ( PARTITION BY topic_id ORDER BY SCORE DESC ) as percent_rank
FROM posts ) AS x
2014-02-27 11:45:20 +11:00
/ *where* / " )
builder . where ( " x.id = posts.id AND
2013-09-30 16:59:16 +10:00
( posts . percent_rank IS NULL OR x . percent_rank < > posts . percent_rank ) " )
2013-03-22 15:43:57 -04:00
2014-02-27 11:45:20 +11:00
filter_topics ( builder , min_topic_age )
builder . exec
end
def update_topics_rank ( min_topic_age )
builder = SqlBuilder . new ( " UPDATE topics AS t
2013-11-18 12:48:26 -05:00
SET has_summary = ( t . like_count > = :likes_required AND
2013-03-28 13:02:59 -04:00
t . posts_count > = :posts_required AND
2013-03-29 12:54:16 -04:00
x . max_score > = :score_required ) ,
2013-03-28 13:02:59 -04:00
score = x . avg_score
FROM ( SELECT p . topic_id ,
2013-03-29 12:54:16 -04:00
MAX ( p . score ) AS max_score ,
2013-03-28 13:02:59 -04:00
AVG ( p . score ) AS avg_score
FROM posts AS p
GROUP BY p . topic_id ) AS x
2014-02-27 11:45:20 +11:00
/ *where* / " )
builder . where ( " x.topic_id = t.id AND
2013-09-30 16:59:16 +10:00
(
( t . score < > x . avg_score OR t . score IS NULL ) OR
2013-11-18 12:48:26 -05:00
( t . has_summary IS NULL OR t . has_summary < > (
2013-09-30 16:59:16 +10:00
t . like_count > = :likes_required AND
t . posts_count > = :posts_required AND
x . max_score > = :score_required
) )
)
" ,
2013-11-18 12:48:26 -05:00
likes_required : SiteSetting . summary_likes_required ,
posts_required : SiteSetting . summary_posts_required ,
2014-02-27 11:45:20 +11:00
score_required : SiteSetting . summary_score_threshold )
if min_topic_age
builder . where ( " t.bumped_at > :bumped_at " ,
bumped_at : min_topic_age )
end
builder . exec
end
2013-02-25 19:42:20 +03:00
2014-02-27 11:45:20 +11:00
def update_topics_percent_rank ( min_topic_age )
builder = SqlBuilder . new ( " UPDATE topics SET percent_rank = x.percent_rank
2013-03-28 13:02:59 -04:00
FROM ( SELECT id , percent_rank ( )
OVER ( ORDER BY SCORE DESC ) as percent_rank
FROM topics ) AS x
2014-02-27 11:45:20 +11:00
/ *where* / " )
2013-02-05 14:16:51 -05:00
2014-02-27 11:45:20 +11:00
builder . where ( " x.id = topics.id AND (topics.percent_rank <> x.percent_rank OR topics.percent_rank IS NULL) " )
2013-02-05 14:16:51 -05:00
2014-02-27 11:45:20 +11:00
if min_topic_age
builder . where ( " topics.bumped_at > :bumped_at " ,
bumped_at : min_topic_age )
2013-02-05 14:16:51 -05:00
end
2013-10-01 17:11:13 +02:00
2014-02-27 11:45:20 +11:00
builder . exec
end
def filter_topics ( builder , min_topic_age )
if min_topic_age
builder . where ( ' posts . topic_id IN
( SELECT id FROM topics WHERE bumped_at > :bumped_at ) ' ,
bumped_at : min_topic_age )
2013-02-05 14:16:51 -05:00
end
2014-02-27 11:45:20 +11:00
builder
end
2013-02-05 14:16:51 -05:00
end