怖話.jpのランキングの実装を考える。(ニコニコ動画で言えば総合ランキング)

下記の様に各怖い話のスコアを算出してそれでソートする。

スコア = PV数 + 怖いの数 * 1000 + コメント数 * 100

("怖いの数"というのはニコニコ動画で言えば"マイリスト数")

当分の間、特殊なランキングアルゴリズムは必要無いだろう。1000と100という重みは定数にして様子を見ながら変えていく。

人気サイトであれば裏で集計すべきだけどまだ貧弱サイトなので毎回サブクエリで集計してしまおう。

select * from stories order by view + (select count(*) from scares where scares.story_id = stories.id) * 1000 + (select count(*) from comments where comments.story_id = stories.id) * 100 desc, id desc;

我ながらとっても遅そうなクエリだ。

class Story < ActiveRecord::Base
  scope :order_by_ranking, order("view + (select count(*) from scares where scares.story_id = stories.id) * #{Scare::RANKING_WEIGHT} + (select count(*) from comments where comments.story_id = stories.id) * #{Comment::RANKING_WEIGHT} desc, stories.id desc")
end
Story.order_by_ranking.page(params[:page]).per(50)

ActiveRecordとkaminariのお陰でスマートな見た目にできたが、気をつけて実行しなければならない重いsocpeになってしまった。

Comments


Option