繁体   English   中英

比较Grails中的域对象之间的关联

[英]Compare associations between domain objects in Grails

我不确定是否要采用最佳方法,但是我将尽力解释我要做什么。

我有以下领域课程

类User {static hasMany = [目标:目标]}

因此,每个用户都有一个目标对象列表。 我希望能够获得一个User实例,并在其目标列表中返回5个用户(具有该实例)的匹配Goal对象数量最多。

有人可以请我解释一下我该怎么做吗?

实现此目的的最简单,最有效的方法是使用普通SQL。 假设您有这些表

users      [id]
goals      [id, description]
user_goals [user_id, goal_id]

您可以使用以下查询执行所需的操作:

set @userId=123;
select user_id, count(*) as matched from user_goals
where user_id!=@userId
  and goal_id in (select ug.goal_id from user_goals ug where ug.user_id=@userId)
group by user_id order by matched desc limit 5;

这将获取一个用户ID,并返回具有匹配目标的其他用户的列表,并按匹配次数排序。 将其包装在GoalService ,您就完成了!

class GoalService {
  def findUsersWithSimilarGoals(user) {
    // ...
  }
}

也可以使用条件或HQL来执行此操作,但是使用此类查询通常更容易使用SQL。

如果您正在寻找简单的匹配项,那么最简单的方法可能是对每个目标进行一次findAll,然后计算每个其他用户出现在结果中的结果数:

Map user2Count = [:]
for (goal in myUser.goals){
    for (u in User.findAllByGoal(goal)){
         def count = user2Count.containsKey(u) ? user2Count.get(u) : 0
         count++
         user2Count.put(u, count)
    }
}
// get the top 5 users
def topUsers = user2Count.entrySet().sort({ it.value }).reverse()[0..5]

根据您的需要,这可能太慢,但是很简单。 如果许多用户共享相同的目标,则可以缓存findAllByGoal的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM