Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 通过相关多对多关联的计数获取记录顺序 斯内里奥:_Ruby On Rails_Postgresql_Join_Activerecord_Related Content - Fatal编程技术网

Ruby on rails 通过相关多对多关联的计数获取记录顺序 斯内里奥:

Ruby on rails 通过相关多对多关联的计数获取记录顺序 斯内里奥:,ruby-on-rails,postgresql,join,activerecord,related-content,Ruby On Rails,Postgresql,Join,Activerecord,Related Content,正在列出电影、电视节目和游戏。在每个资源(电影、电视节目等)的显示页面上,我们要列出相关资源 模式: 希望这个问题有意义 更新:寻找仅SQL的解决方案。我不需要将结果缓存在任何其他表中。如果您正在rails代码中找到解决方案,那么它可能会解决您的问题 def related_movies scores_hash = {} Movie.joins(:resource_genres).where('resource_genres.genre_id' => resource_genres

正在列出电影、电视节目和游戏。在每个资源(电影、电视节目等)的显示页面上,我们要列出相关资源

模式: 希望这个问题有意义


更新:寻找仅SQL的解决方案。我不需要将结果缓存在任何其他表中。

如果您正在rails代码中找到解决方案,那么它可能会解决您的问题

def related_movies
  scores_hash = {}
  Movie.joins(:resource_genres).where('resource_genres.genre_id' => resource_genres.pluck(&:genre_id)).where.not(id: self.id).distinct.find_each do |movie|
    scores_hash[movie] = (movie.resource_genres.pluck(:genre_id) & self.resource_genres.pluck(:genre_id)).count
  end
  Hash[scores_hash.sort_by { |movie, score| -score }].keys
end

加入后,您需要按电影ID的组数进行订购
resource\u genres
,请查看以下纯SQL方法:

方法#1(单个查询) 在自身上双击
资源\u流派
表以维护自身流派ID:

def related_movies
   Movie.select("movies.*, COUNT(*) AS group_count").
   joins(:resource_genres).
   joins("JOIN resource_genres rg ON rg.genre_id = resource_genres.genre_id").
   where("rg.resource_type = 'Movie' 
          AND rg.resource_id = ? 
          AND movies.id != ?", self.id, self.id).
   group('movies.id').
   order('group_count DESC')
end

方法2(2个查询) 在单独的查询中从self
resource\u genres
中提取
genre\u id

def related_movies
   Movie.select("movies.*, COUNT(*) AS group_count").joins(:resource_genres).
   where("resource_genres.genre_id IN (?) 
         AND movies.id != ?", self.resource_genres.pluck(:genre_id), self.id).
   group('movies.id').
   order('group_count DESC')
end

你要用多少张唱片?将ActiveRecord用于几百部电影可以,但此查询无法缩放。@eabraham实际上只需要前10条相关记录:)前10条是指前10条吗?可能重复@eabraham耶,前10条是指前10条。条目将按最大匹配数排序,因此前十名也将是前十名:)连接的更好方法是
Movie.join(:genres)。其中('genres.id IN(?),genres.pulk(:id))
我正在寻找纯SQL的解决方案:)如果你有一个关于流派名称的索引,那么我的解决方案和你的解决方案的性能将是相同的:)你可以处理
X。相关的电影
不应该返回
X
幕后
电影。连接(:流派)
是3个表的连接,对
movie.genres
的每次调用也是如此。因此,您可以考虑使用ReaseCyGyRes表,而添加一些急切的加载。@ MaMaDeDaa27,谢谢您指出。我已经做出了改变,我真的很感谢你的帮助:)我现在就用第二个答案。将在几天内在这里进行基准测试并发布哪个查询更有效。谢谢你的回答,并祝贺你的赏金:)顺便说一句,我错过了:“电影。*,算了(*)作为组_算了”我很高兴这有帮助
def related_movies
   Movie.select("movies.*, COUNT(*) AS group_count").
   joins(:resource_genres).
   joins("JOIN resource_genres rg ON rg.genre_id = resource_genres.genre_id").
   where("rg.resource_type = 'Movie' 
          AND rg.resource_id = ? 
          AND movies.id != ?", self.id, self.id).
   group('movies.id').
   order('group_count DESC')
end
def related_movies
   Movie.select("movies.*, COUNT(*) AS group_count").joins(:resource_genres).
   where("resource_genres.genre_id IN (?) 
         AND movies.id != ?", self.resource_genres.pluck(:genre_id), self.id).
   group('movies.id').
   order('group_count DESC')
end