Сравните ассоциации между объектами домена в Grails - PullRequest
1 голос
/ 08 апреля 2010

Я не уверен, пойду ли я лучше всего, но я постараюсь объяснить, что я пытаюсь сделать.

У меня есть следующие классы домена

класс User { static hasMany = [цели: цель] }

Таким образом, у каждого пользователя есть список объектов цели. Я хочу иметь возможность взять экземпляр пользователя и вернуть 5 пользователей с наибольшим количеством совпадающих объектов цели (с экземпляром) в списке целей.

Может ли кто-нибудь любезно объяснить, как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 08 апреля 2010

Если вы ищете простое совпадение, возможно, самым простым способом было бы сделать 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]

Thisможет быть слишком медленным, в зависимости от ваших потребностей, но это просто.Если у многих пользователей одинаковые цели, вы можете кэшировать результаты findAllByGoal.

0 голосов
/ 08 апреля 2010

Самый простой и эффективный способ добиться этого - использовать простой 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;

Принимает идентификатор пользователя и возвращает список других пользователей с совпадающими целями, отсортированный по количеству совпадений. Заверните это в GoalService и все готово!

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

Также возможно сделать это с помощью критериев или HQL, но с такими запросами обычно проще использовать SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...