I want to compile a list of recommended friends.
What I was thinking was something like this (this is semi pseudo (sudo) code!):
recommended_friends = []
friends.each do |friend|
while recommeded_friends.length < 10
friend.friends.each do |friend|
if friend.in?(recommeded_friends)
recommeded_friends[friend][counter] += 1
else
recommeded_friends << [friend, 0]
end
end
end
end
But this obviously doesn't work. How would you guys approach this?
Thanks for any suggestions.
The tables (some are shortened):
Users:
id | name
Friendships
id | user_1_id | user_2_id | requested_at | accepted_at | declined_at |
A friendship between user1 and user2 only occurs once in the DB.
UPDATED. Try something like this, it should work:
recommended_friends = {}
friends.each do |friend|
if recommeded_friends.length < 10
friend.friends.each do |other_friend|
if other_friend != this_user # exclude myself
recommeded_friends[other_friend] =
(recommeded_friends[other_friend] | 0) + 1
end
end
end
end
recommendend_friends.sort_by{|key, value| value}.reverse
top_ten = recommended_friends.first(10).map{|a| a[0]}
SQL version:
Users.find_by_sql([
"SELECT u.*
FROM
(SELECT f2.id, f2.user_1_id u_1_id, f2.user_2_id u_2_id, (count(f1.id)) cnt
FROM friendships f1
JOIN friendships f2 ON f1.user_1_id = f2.user_1_id
OR f1.user_2_id = f2.user_1_id
OR f1.user_2_id = f2.user_2_id
OR f1.user_1_id = f2.user_2_id
WHERE (f1.user_1_id = ? OR f1.user_2_id = ?)
AND (f2.user_1_id <> ? AND f2.user_2_id <> ?)
GROUP BY f2.id, f2.user_1_id, f.user_2_id
HAVING count(f2.id) = 1
ORDER BY cnt DESC) fs
JOIN friendships ff ON ff.user_1_id = fs.u_1_id
OR ff.user_2_id = fs.u_1_id
OR ff.user_2_id = fs.u_2_id
OR ff.user_1_id = fs.u_2_id
JOIN users u ON
CASE WHEN (ff.user_1_id = fs.u_1_id OR ff.user_2_id = fs.u_1_id)
THEN fs.u_2_id ELSE fs.u_1_id END = u.id ",
user.id, user.id, user.id, user.id]).first(10)
In theory it should work, take a try.
recommeded_friends will always stay an empty array. You can not do this: recommeded_friends < 10
Try this: recommeded_friends.length < 10
The simplest method I can think of:
recommended_friends = friend.friends.sort do |a,b|
a <=> b # insert your ranking algorithm here
end.take 10
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.