2013-05-01 101 views
2

我試圖找到類似的一組興趣的用戶,下面的模式..匹配利益(最近鄰)搜索

USERS - ID name etc 

Interests - ID UID PID 

其中,ID是興趣唯一的ID,UIS是用戶ID而PID是產品ID。我看過其他類似的問題,但他們都沒有確切的答案。

例 - 比方說,我很感興趣,讓用戶具有相似興趣的約翰,這是兩個表怎麼看也不像......

ID Name 
11 John 
12 Mary 
13 Scott 
14 Tim 

ID UID PID 
3 12 123 
4 12 231 
5 12 612 
6 13 123 
7 13 612 
8 14 931 
9 14 214 
10 11 123 
11 11 231 
12 11 781 
13 11 612 

我想結果,在這個順序。

我正在考慮做一個我感興趣的用戶與所有其他用戶的交集。這聽起來並不是一個很好的解決方案,因爲每當用戶添加興趣或添加其他用戶時都必須完成此任務。這是一個小型項目,截至目前,我將限制用戶數量爲100.我仍然認爲上述方法將不會有效,因爲它需要花費100多天的時間。

有人可以引導我在正確的方向嗎?什麼是可能的解決方案,以及哪個解決方案在上述給定的限制條件下最好。我正在查看ANN以查看我是否可以使用該功能。

+0

如果「類似的興趣」可以被定義爲配套產品ID號,那麼你不需要ANN ... – luksch 2013-05-01 14:36:36

回答

2

這首先計算每個用戶與John有共同的興趣數量。這種方法是把約翰的所有利益,回到利益表,並聚合到共同利益的數量上。這裏是SQL的那個:

select i.uid, COUNT(*) as cnt 
from (select i.* 
     from interests i join 
      users u 
      on i.uid = i.id 
     where u.name = 'John' 
    ) ilist join 
    interests i 
    on ilist.pid = i.pid and 
     ilist.uid <> i.uid -- forget about John 
group by i.uid 

但是,你實際上想要的產品清單,而不只是計數。所以,你必須加入回利益表:

select i.* 
from (select i.uid, COUNT(*) as cnt 
     from (select i.* 
      from interests i join 
       users u 
       on i.uid = i.id 
      where u.name = 'John' 
      ) ilist join 
      interests i 
      on ilist.pid = i.pid and 
       ilist.uid <> i.uid -- forget about John 
     group by i.uid 
    ) t join 
    interests i 
    on t.uid = i.uid 
group by t.cnt, i.uid 
+0

這聽起來像一個很好的解決方案,但它會有多高效? – questions 2013-05-01 14:43:11

+0

這取決於您的索引結構和數據大小。對於您的問題中的小數字,查詢應該表現良好。在一個數據庫中,即使100 * 100操作也應該非常快。 – 2013-05-01 14:45:53

+0

關於索引,來自興趣的ID將成爲主鍵,並且正在考慮UID和PID上的索引。你有什麼建議? – questions 2013-05-01 14:52:26

0

以下查詢根據用戶11.

SELECT in2.UID FROM users u 
INNER JOIN interest in1 ON (in1.UID = u.ID) 
INNER JOIN interest in2 ON (in2.PID = in1.PID AND in2.UID <> u.ID) 
WHERE u.ID = 11 
GROUP BY in2.UID 
HAVING COUNT(in2.UID) >= 2 
ORDER BY COUNT(in2.UID) DESC 

的ORDER BY確保用戶最相似的興趣第一結束利益發現其他用戶提供至少2分或更多類似的利益。 HAVING COUNT(in2.UID)> = 2)確保找到的用戶擁有至少2個或更多類似的興趣。