[英]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.