如何让这个请求急切加载

时间:2014-08-14 21:50:53

标签: ruby-on-rails collaborative-filtering

我正在尝试在具有6k项和30k用户的小型数据库中执行集体过滤相似性算法。这是我大学的一个研究项目;我不是计算机科学家;而是一个超级用户。数据已经用特定键指定;为了节省计算机时间,我创建了与现有密钥的关联。

在我的算法中,此代码段的执行时间最长:

def aveRankings(item,user = nil)
  #period
  begdate = '2013-08-10 00:00:00 -0400' #Time.parse('2013-08-10')
  enddate = '2014-08-10 00:00:00 -0400' #Time.parse('2014-08-10')
  if user.nil? then
    return item.rankings.where(created_at: (begdate..enddate) ).average(:value).to_f
  else
    return user.items.where(created_at: (begdate..enddate), ikey: item.ikey).average(:value).to_f
  end
end

我在网上读到有关n + 1以及它如何背叛性能的内容。我试着调用.include(:排名)来急切加载排名,但代码的行为并不像预期的那样。

这是与项目的关联:

class Item < ActiveRecord::Base
.
.

has_many :useritems, foreign_key: "ukey", primary_key: "ukey"
has_many :items, through: :useritems

.
.
end

Similarity algorithm

非常感谢任何建议。

编辑:我应该包含这个

commonUsers.each do |commonuser|
  a = aveRankings(item,commonuser)
  b = aveRankings(candidateitem,commonuser)
  if a != 0.0 and b != 0.0 then #mysql ave function returns this for 0 rankings
     arra << a - aveRankings(item)
     arrb << b - aveRankings(candidateitem)
  end
end

1 个答案:

答案 0 :(得分:0)

这里是你如何避免至少3/4的请求:

aa = aveRankings(item)
bb = aveRankings(candidateitem)
a = nil 

commonUsers.each do |commonuser|
  a = a || aveRankings(item,commonuser)
  b = aveRankings(candidateitem,commonuser)
  if a != 0.0 and b != 0.0 then #mysql ave function returns this for 0 rankings
    arra << a - aa
    arrb << b - bb
  end
end