2011-11-30 217 views
9

我來自MySQL背景,我正試圖圍繞MongoDB環繞我的頭。特別是,我正在努力構思我應該如何模仿n:n關係的「蒙戈方式」。如何在MongoDB中建立多對多關係(對於MySQL用戶)

在這個例子中,假設我們有兩個collectionsusersinterests。我們需要能夠代表或查詢我們的數據幾件事情:

  • 用戶的利益
  • 用戶評價的興趣,例如「喜歡」或「不喜歡」
  • 用戶給定的利率
  • 計數器(可遞增/遞減)的利息各級別
  • 利息名

MySQL,我會在用戶ID 兩個興趣ID上創建了索引爲users_interests的表。對於櫃檯,我會爲每種評級類型設置單獨的列,並且每次用戶評級/取消評級時,都會進行交易,以確保計數永遠不會錯誤。我試過reading about some schema designs,但無濟於事。

你能幫助失落的靈魂找到方法嗎?

回答

10

偉大的問題。讓我先概述一下N:N關係是如何工作的,然後我會詳細討論你的每一個要點。

MySQL中的N:N通常你有你的數據透視表關聯你的用戶和興趣(user_interests表)。在mongo中,你做這個有點不同。您仍然擁有用戶和興趣集合,但是現在,您將存儲用戶感興趣的關鍵字列表。因此,像這樣:

User Collection { 
     "name":"Josh", 
     "user":"jsmith", 
     "interests":[ 
      { 
      "_id":12345, 
      "rating":"like" 
      }, 
      {..}.. 
     ] 
} 

通過存儲在其中鍵入關閉你的興趣表列出你的興趣,你可以執行每次需要的行動。如果您想查詢基於利益表中的ID的查詢,請使用$in modifier進行查詢。

現在爲您的利益收集我會做到以下幾點:

User Interest { 
     "_id":objectId 
     "label":"Swimming", 
     "count":intValue 
} 

當添加感興趣的用戶文檔,則計數變量會那麼依賴於你的等級的定義。如果您將評分存儲在單獨的區域(或邏輯)中,則分配給它們的值將與您感興趣的整數值相關。 IE:用戶評價它meh(值爲1),然後你將計數值加1。

希望這會有所幫助,至少會帶來一些關於如何構建它的其他想法!

祝你好運,記得MONGO真是太棒了。

+0

爲什麼要存儲該ID?您不太可能重新命名利益,但保留參考,對吧?另外,你必須執行'$ in'來顯示喜歡的名字。 – mnemosyn

+0

@mnemosyn通常情況下,你有兩種情況之一的代碼路徑:1:你有興趣想看看哪些用戶有,或者2:你想看看用戶有哪些興趣。首先,你已經有了這個名字,現在你只需要對一個ID(更快的查詢)而不是一個字符串進行查詢。第二,你有一個ID列表,你再次在對象ID上查詢。此外,如果您更改興趣名稱,則不必通過每個用戶條目進行重構來更新興趣名稱,因爲您需要的僅僅是興趣收集中特定興趣的引用ID。希望這可以幫助! – Petrogad

+0

@mnemosyn如果我決定大寫的興趣,從「釣魚」到「釣魚」或什麼? – ceejayoz

1

要維護每個興趣的評分的全球統計數據,您需要一個獨立且獨立的集合,您可以使用原子更新運算符更新(添加或減去)評分,並在用戶執行喜歡/不喜歡的興趣操作時更新。

您可以將每個用戶的興趣存儲爲用戶集合本身內的一系列子文檔。

類似

這些數據的JSON結構會是這樣:

db.User 
{ 
    name: 'joe', 
    ...., 
    interests : [{ name: 'swimming', rating: 10}, 
       { name: 'cooking', rating: 22 } 
       ] 
} 

現在你可以使用內部鍵查詢:

> db.User.find({ "interests.name" : "cooking" }) 

這將返回誰具有特定興趣的用戶。

+0

這樣,每個用戶的評分都是非標準化的,即每個用戶都有一份全球評級('評級:101)這不能保持。 – mnemosyn

+0

評分和計數之間存在差異。計數是全球性的,評分是相對於用戶的。評級應該是一個字符串,但不是一個整數。 –

+0

好的,我誤解了OP的問題。 – mnemosyn