加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 按相关的多对多关联计数获取记录

发布时间:2020-12-16 21:03:45 所属栏目:百科 来源:网络整理
导读:Scnerio: https://www.funtraker.com正在列出电影,电视节目和游戏.在每个资源(电影,电视节目等)的显示页面上,我们要列出相关资源. 架构: class Movie AR::Base has_many :resource_genres,as: :resource has_many :genres,through: :resource_genresendcla
Scnerio:

https://www.funtraker.com正在列出电影,电视节目和游戏.在每个资源(电影,电视节目等)的显示页面上,我们要列出相关资源.

架构:

class Movie < AR::Base
  has_many :resource_genres,as: :resource
  has_many :genres,through: :resource_genres
end

class ResourceGenre
  belongs_to :resource,polymorphic: true
end

现在我想得到一个基于匹配类型的相关电影列表(两部电影都是相关的,如果它们都有’喜剧’类型).这些相关电影需要按最大匹配类型排序.

那么这里是样本电影和预期的输出.

#Input
Movie         Genres
Movie 1:      horror,comedy,action,war
Movie 2:      action,thriller,crime,animation  
Movie 3:      comedy,war,thriller
Movie 4:      crime,animation,war

#Expected output
movie1.related_movies => [ movie3,movie2  ]
movie4.related_movies => [ movie2,remaining-three-movies-in-any-order ]
movie3.related_movies => [ movie1,movie2,movie4]

希望问题有意义.

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

解决方法

您需要在加入后按电影ID的组计数进行排序
resource_genres,看看下面的纯SQL方法:

方法#1(单个查询)

双重加入resource_genres表以保持自我类型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_genres中获取genre_ids.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读