我已经在这个网站上到处找过了,但似乎没有一个是我要找的。他们中的很多人都在谈论Facebook是如何做到的,或者Twitter是如何向粉丝推荐的,但即便如此,他们也没有给出任何直截了当的答案。
所有我发现的都是使用两个用户ID计算共同的朋友。
我希望能够获取登录用户的ID,查看他们的朋友,并通过他们的朋友来计算与登录用户有最多共同朋友的人,以建议人们添加有最多共同朋友的人。
我正在使用PHP和MySQL来实现这一点。我就是不知道该怎么做。
我的友谊桌是这样的:
---------------------------------
| friend1 | friend2 | pending |
---------------------------------
| 1 | 2 | 0 |
| 2 | 1 | 0 |
| 3 | 1 | 0 |
| 1 | 3 | 0 |
---------------------------------
此表显示用户1是2和3的朋友
2不是3的朋友,而是1的朋友。
所以,如果用户登录到用户id 2,我希望它建议用户id 3,因为他们都是用户id 1的朋友。
到目前为止我所拥有的:
public function friendList($user_id = null){
if(!$user_id){
$user_id = $this->_data->user_id;
}
$query = "SELECT friend2 FROM user_friends WHERE pending = 0 AND ((friend1 = ".$user_id.") AND (friend2 IN (SELECT user_id FROM users WHERE active = 1 AND user_id = friend2)))";
$data = $this->_db->hardquery($query);
return $data->results();
}
public function suggestUsers(){
$user_id = $this->_data->user_id;
$my_friends = array();
$suggest_friends = array();
foreach($this->friendList() as $friend){
array_push($my_friends,$friend->friend2);
}
foreach($my_friends as $friend_id){
foreach($this->friendList($friend_id) as $friendOfFriend){
$friendOfFriend = $friendOfFriend->friend2;
if(!in_array($friendOfFriend,$my_friends) && $friendOfFriend != $user_id){
array_push($suggest_friends,$friendOfFriend);
}
}
}
foreach($suggest_friends as $sgf){
$sgf = new user($sgf);
$sgf = $sgf->data();
echo "<a href=\"#\">".$sgf->display."</a><br>";
}
}
它可以工作,列出用户朋友的朋友,但没有添加用户。。。
然而,我不能根据谁的共同朋友最多来分类,我想这是可以的(尽管我想如果可以的话),但这似乎也不是一个非常有效的方法。。
这似乎需要花费大量的资源来浏览用户的所有好友,特别是如果用户添加了几百到一千个好友,并且他们添加了几百到一千个好友,等等。
我对高级SQL不太熟悉,所以我不知道该怎么做。
最佳答案
下面是对1个查询执行此操作的尝试。其思想是选择friend2
列表,并将其加入到friend2
所在的select中。然后,使用friend1
,我们可以返回根据友谊的相关性排序的行,以及与该人是朋友的每个人。
SELECT
a.friend2,
COUNT(*) as relevance,
GROUP_CONCAT(a.friend1 ORDER BY a.friend1) as mutual_friends
FROM
user_friends a
JOIN
user_friends b
ON (
b.friend2 = a.friend1
AND b.pending = 0
AND b.friend1 = LOGGED_IN_USER
)
WHERE
a.pending = 0
AND
a.friend2 != LOGGED_IN_USER
GROUP BY
a.friend2
ORDER BY
relevance DESC;
AsqlFiddle example - http://sqlfiddle.com/#!9/3dbf0/3
编辑
在我最初的查询中,我忘记排除已经是
GROUP BY
好友的任何用户。在不存在友谊的情况下,使用LOGGED_IN_USER
和LEFT JOIN
,这将返回你想要的结果。SELECT
a.friend2,
COUNT(*) as relevance,
GROUP_CONCAT(a.friend1 ORDER BY a.friend1) as mutual_friends
FROM
user_friends a
JOIN
user_friends b
ON (
b.friend2 = a.friend1
AND b.pending = 0
AND b.friend1 = LOGGED_IN_USER
)
LEFT JOIN
user_friends c
ON
(
c.friend2 = a.friend2
AND c.pending = 0
AND c.friend1 = LOGGED_IN_USER
)
WHERE
a.pending = 0
AND
c.friend1 IS NULL
AND
a.friend2 != LOGGED_IN_USER
GROUP BY
a.friend2
ORDER BY
relevance DESC;
更新sqlFiddle example - http://sqlfiddle.com/#!9/c38b5c/2