2012-11-30 35 views
10

鑑於以下與100,000名朋友競爭的模式,我有興趣爲我的需求找到最高效的模式。MongoDB嵌入與數組子文檔性能

文檔1(指數上USER_ID)

{ 
"_id" : "…", 
"user_id" : "1", 
friends : { 
    "2" : { 
     "id" : "2", 
     "mutuals" : 3 
    } 
    "3" : { 
     "id" : "3", 
     "mutuals": "1" 
    } 
    "4" : { 
     "id" : "4", 
     "mutuals": "5" 
    } 
} 
} 

文檔2

{ 
"_id" : "…", 
"user_id" : "1", 
friends : [ 
    { 
     "id" : "2", 
     "mutuals" : 3 
    }, 
    { 
     "id" : "3", 
     "mutuals": "1" 
    }, 
    { 
     "id" : "4", 
     "mutuals": "5" 
    } 
]} 

我似乎無法找到的任何信息(化合物的多鍵上user_id的& friends.id指數)子字段檢索的效率。我知道mongo在內部將數據實現爲BSON,所以我想知道這是否意味着投影查找是二進制O(log n)?

具體來說,給定一個user_id來查找是否存在friend_id的朋友,那麼每個模式上的兩個不同查詢會如何比較? (假設上述索引)請注意,返回的內容並不重要,只有在朋友存在時才返回null。

Doc1col.find({user_id : "…"}, {"friends.friend_id"}) 
Doc2col.find({user_id : "…", "friends.id" : "friend_id"}, {"_id":1}) 

另外值得關注的是$ set修飾符是如何工作的。對於架構1,給定查詢Doc1col.update({user_id : "…"}, {"$set" : {"friends.friend_id.mutuals" : 5}),friends.friend_id上的查找工作如何?這是一個O(log n)操作(其中n是朋友的數量)?

對於模式2,查詢Doc2col.update({user_id : "…", "friends.id" : "friend_id"}, {"$set": {"friends.$.mutuals" : 5})與上述數據的比較如何?

+3

與數組樣式(Doc2)一起使用,動態鍵幾乎從來都不是正確的方法。另外,不要使用明智的引號(這不是合法的語法,而且很難閱讀)。 – JohnnyHK

+1

我想Doc2會像一些額外的存儲空間一樣用完,但是@JohnnyHK說Doc1並不是一個好方法,請相信我使用Doc1的人的問題數量,然後意識到他們必須轉向Doc2來做任何事情與他們的架構... – Sammaye

+0

感謝您的意見。 @Sammaye爲什麼Doc2會佔用幾個字節的額外存儲空間?你指的是索引嗎?順便說一句聰明的報價是從複製粘貼 –

回答

1

如果一個人的主要需求是將數據呈現給用戶界面以便於管理,那麼doc1更可取。其簡單的使用投影{}, {friends.2 : 1}

DOC2是你最強的對手,只過濾出所需的數據,因爲你的使用情況不關心結果注意,它並不真正的問題是怎麼返回和索引將加快取。

上DOC2的頂部允許更清潔的語法

db.doc2.findOne({user_id: 1, friends.id : 2}) 

db.doc1.findOne({ $and : [{ user_id: 1 }, { "friends.2" : {$exists: true} }] }) 

最後值得注意的是,然而,一個可以創建DOC1一個sparse index(並使用$存在),但你有10萬個朋友的可能性 - 每個朋友都需要一個稀疏的索引 - 這使得這個荒謬。反對合理數量的條目說人口統計學性別[男性,女性],年齡組[0-10,11-16,25-30,]或更多impt事物[杜松子酒,威士忌,伏特加,...]