我不确定我是否会以最好的方式解决这个问题,但我会尝试解释我想要做的事情。
我有以下域类
类用户{ static hasMany = [目标:目标] }
因此每个用户都有一个Goal对象列表。我希望能够获取一个User实例,并在目标列表中返回具有最多匹配目标对象(带有实例)的5个用户。
有人可以解释一下我可能会这样做吗?
答案 0 :(得分:0)
实现此目的的最简单,最有效的方法是使用纯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。
答案 1 :(得分:0)
如果你正在寻找一个简单的匹配,也许最简单的方法是为每个目标做一个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的结果。