我正在为我的项目中的用户构建推荐方法。用户在查看,创建,评论或与对象交互时会生成兴趣记录(根据操作加权)。
我编写了一个查找用户兴趣的查找方法,然后找到对这些项目感兴趣的用户。然而,它的效率非常低,可以根据用户的兴趣(最多50个)进行尽可能多的数据库调用。
以下是正在发生的事情的简要版本:
#User.rb
...
has_many :interests, :as => :interestable, :dependent => :destroy
def recommendations
recommendations = []
Interest.for(self).limit(50).each do |item|
recommendations << Interest.other_fans_of(item)
end
user_ids = recommendations.flatten.map(&:user_id).uniq
end
...
#interest.rb
...
belongs_to :user
belongs_to :interestable, :polymorphic => true
named_scope :for, lambda { |user| { :conditions => { :user_id => user.id } } }
named_scope :limit, lambda { |num| { :limit => num } }
named_scope :other_fans_of, lambda { |interest| { :conditions => { :interestable_type => interest.interestable_type, :interestable_id => interest.interestable_id } } }
default_scope :order => "weight DESC"
...
是否有任何sql天才可以把它变成一个很好的干净db调用?
答案 0 :(得分:0)
这样的事情应该可以胜任。可能有更漂亮的方式......
class User < ActiveRecord::Base
#...
def recommendations
# get a list of the relevant interests
the_interests = Interest.for(self).limit(50).map{|x| [x.interestable_type, x.interestable_id]}
# make some sql
conditions = the_interests.map{|x| "(`interestable_type`=? AND `interestable_id`=?)"}.join(" OR ")
# use ruby magic to make a valid finder and get the other user_ids
user_ids = Interest.all(:select => '`user_id`', :conditions => [conditions, *(the_interests.flatten)]).map(&:user_id).uniq
end
#...
end