2012-06-28 18 views
1

我正在開發一個Web應用程序,用戶將向系統上傳大量文檔,並在文檔上執行不同類型的操作(包括聚合)。然而,每個用戶上傳的文檔數量差別很大 - 有些可能會上傳一打文檔,有些可能會上傳一百萬個文檔。用於大量文檔的分片鍵(MongoDB)

文件看起來像這樣:

doc{ 
    _id: <self generated UUID>, 
    uid: <id of user who uploaded the document>, 
    ctime: <creation timestamp>, 
    .... 
     <other attributes, etc> 
    .... 
} 

現在這裏是在選擇片鍵的問題:如果我選擇的UUID作爲片鍵
1,同一用戶上傳的文件是不可能的最終在同一個分片中,聚合操作將會很昂貴。
2.如果我使用uid作爲分片鍵,那麼存儲在分片中的數據將不會均勻。

任何人都可以建議哪個是最好的方法來實現這個?

我對分區和分片非常陌生,我對谷歌以及堆棧溢出的研究沒有產生任何結果。如果需要,我可以更改文檔的模式,因爲項目仍處於設計階段。

+0

你想怎麼辦查詢數據? –

回答

3

這是我見過的選擇片鍵的最佳指南:http://www.kchodorow.com/blog/2011/01/04/how-to-choose-a-shard-key-the-card-game/

你必須決定要如何查詢數據。也許,uid和ctime的組合會產生一個好的分片鍵,但我不確定這是否會在查詢時導致你悲傷,因爲你沒有對如何計劃查詢給出太多的見解。

+0

感謝您的鏈接。我現在要通過它,但似乎有點混亂。 我想根據UUID或(uid,parentid)的組合來查詢數據。這就是全部 - 其他領域無論如何都會從文檔變爲文檔。僅供參考,父母是父母文檔的id(如wordpress頁面)。 但是我會運行一些像count_child_docs(parentid)這樣的遞歸掃描「樹」的函數。這就是爲什麼我想盡可能在​​單個碎片上存儲數據的原因。 我想在(uid,parentid)上創建密鑰,但parentid可以更改,因此更新可能會很昂貴。 –

+0

我再次通過文章,並在那裏提供的演示。我認爲我的案例最好的關鍵是(uid,UUID)。但我猜想必須保持小塊大小,以便以非常低的上傳數量優化用戶。 @ wes-freeman:你的意見是? –

+0

你的想法聽起來不錯。絕對值得在測試中給它一個鏡頭 - 確保你測試插入(以確保它們不會全部進入同一個碎片)和查詢(以確保它們大多數要去1-2個碎片並避免很多合併)。不過,我認爲你不需要保持塊大小。你的uuid查詢可以包含uid,還是不知道? –