2014-10-30 118 views
1

我很努力地爲應用程序找到最好的數據庫設計。我有一個SQL背景,傾向於創建一個或多或少的非規範化數據庫設計。Mongo DB Schema Design

我有以下問題。我收集了大約2000篇文章的「文章」。每篇文章都有相當多的信息。實施推薦系統時,我想爲每個「文章」將每個「用戶」和「預測評分」關聯起來。 在SQL中,我將使用三個表對這個模型進行建模:「文章」,「用戶」,「UserToArticle」。 查詢應該如下:我想爲每個「Article」關聯當前登錄的用戶的「PredictedRating」。在SQL中,我將通過「Article」和「Users」預先選擇相應的用戶。 擁有正確的索引非常快。

我怎麼能用mongo的方式實現這個?當我用所描述的方式實現這個時,我不得不爲每篇文章設置一個findOne()查詢,這是非常低效和緩慢的(即使在使用索引時)。

你有什麼想法嗎?重要的是,只發布當前用戶的預測評級。

+0

目前尚不清楚你需要什麼類型的查詢。例如,一個用戶的所有評分或一篇文章的全部評分? – 2014-10-30 16:12:25

+0

好點:我需要一位用戶的所有評級。 – Basil 2014-10-31 12:54:16

回答

2

規則拇指

的MongoDB的博客有一些good advice on data modeling

  1. 使用嵌入文檔只要有可能。
  2. 如果一個子文檔經常自己讀取,最好不要嵌入它。
  3. 保持陣列小。如果嵌入的文檔數組不斷增長,請將其替換爲參考ID數組。如果引用數組不斷增長,請嘗試反轉引用或將引用提取到它自己的集合中。
  4. 應用程序級別的連接仍然是一個選項。正確使用索引和投影時,不應該有性能下降。
  5. 您可以嵌入很少更新但經常讀取的文檔,即使這意味着冗餘數據。如果您需要頻繁更新冗餘數據,請不要嵌入冗餘數據,因爲這可能會超過讀取優勢。
  6. 針對您的應用優化您的數據模型。需要一起閱讀或編寫的內容應該更接近(更少的集合)。

因此,對文檔數據庫建模並不像標準化關係數據模型那麼簡單。當你掌握了這些經驗法則時,你應該閱讀about data models in the MongoDB manual


我們要放三個域對象到MongoDB的:用戶文章已預測評級。我假設有很多用戶和更多的文章。很明顯,我們不應該把用戶和文章放到一個集合中(子彈2,子集4和子集5)。因此,我們只需要決定放置預測評級的位置。

嵌入收視成篇

隨着你的使用情況是獲得一個用戶的所有預測收視率,這將是適得其反把它們放進文章(6)。您需要搜索所有文章才能獲得評分。除此之外,如果您刪除用戶,則需要更新每篇文章。

嵌入到收視用戶

嵌入到收視用戶的優點是,你只需要一個查詢來獲取用戶和評級數據。但是你可能想爲每篇文章給每個用戶添加一個評級,因此這些數組將增長到很多(3)。

把收視率到它自己的收藏

因此它是可行的把收視率到自己的收藏。

{ 
    _id: ObjectId("f01..."), 
    userId: ObjectId("123..."), 
    articleId: ObjectId("abc..."), 
    predictedRating: 5.4 
} 

如上所述,這取決於您的數量結構。如果您的用戶只有很少或文章很少,那麼嵌入預測的評分可能是更簡單快捷的解決方案。