2015-12-27 84 views
0

在StackOverflow上一樣(沒有什麼關係,但它是一個很好的例子)的應用程序,我們有Question秒。我們的mongodb的集合中的每個Question具有Answer秒的陣列,和Vote秒(或者upvoting或downvoting)的陣列。MongoDB - 子子女?

在每個Answer中,有可能User對其投票或降低投票。

所以該模式會是這個樣子:

Question 
    -> Answers [] 
    -> Votes [] 
     -> value (-1/1) 
     -> username 
    -> Votes [] 
    -> value (-1/1) 
    -> username  
    -> question_text, etc. 

從一個MySQL背景這個模式感到「噁心」來,但我一直深信這是一種行業慣例。

現在,我目前需要向每位用戶展示他們已投票的內容,包括Question s和Answer s。

所以,如果我必須找到一個用戶投票的Answer,我想正是如此查詢(在節點):

question_collection.find(
    {'question.answers.votes.username': username}, function(e,d) { 
    /* do stuff */} 
); 

該查詢變爲4級深。這是一個正常的做法,或者我應該在模式中引入一些規範化?

回答

1

MongoDB的優點之一是您可以將一個Question的所有相關信息放在一個文檔中,因此您只需要1個數據庫查詢並且不需要任何聯接即可獲取所有信息以渲染Question

但是,如果你想找到的一切用戶已經投票,事情變得有點複雜。當然,你可以做你所做的事,儘管它不會贏得任何表演獎。

或者,您可以複製在一個巧妙的方法將數據訪問它在一個簡單的方法。例如,您可以添加兩個數組到User型號:

QuestionsVoted: [{ id1: +1}, {id2: -1}, {id3: +1}], 
AnswersVoted: [{ id4: +1}, {id5: -1}] 

這意味着你需要保持這個數據同步:當一個問題或回答用戶的投票,你需要更新這兩個問題和用戶。這並不壞,因爲數據很少被寫入並且經常被讀取。

如果你有一個帶票對付自己,選票的統計例如隨着時間的推移,或按地理區域,您可能希望創建一個Vote集內的其他要求。是的,那麼您將不得不保持3個集合中的數據同步。

在技術上可以在MongoDB中創建外鍵,但在這種情況下我不會推薦它。你會失去MongoDB的一些好處,因爲它不擅長連接(它需要2個獨立的查詢)。

你可以閱讀更多關於如何在MongoDB中on their blog設計關係。