2012-03-06 92 views
20

我正在實現處理相當多的字段的聯繫人數據庫。他們中的大多數是預定義的,可以被認爲是綁定的,但有一些不是。我們會將這些字段中的一個稱爲「組」。目前,我們實現它的方式是(每個文件/聯繫人有「羣體」字段):對象數組與對象的Mongo索引

'groups' : { 
    152 : 'hi', 
    111 : 'group2' 
} 

但一些閱讀後,我就把它似乎我應該這樣做:

'groups' : [ 
    { 'id' : 152, 'name' : 'hi' }, 
    { 'id' : 111, 'name' : 'group2' } 
    ... 
] 

和然後應用索引db.contact.ensureIndex({'groups.id':1});

我的問題是關於功能。這兩種結構之間有什麼區別,以及索引是如何建立的(它是簡單地在每個文檔/聯繫人中索引,還是構建一個包含所有文檔/聯繫人所有組的全面索引?)。

我很喜歡這種假設,這在結構上是最好的方式,但如果我不正確,請告訴我。

回答

35

在第二種情況下,查詢一定會容易得多,其中「groups」是一組子文檔,每個文檔都有一個「id」和「name」。

Mongo不支持「通配符」查詢,所以如果你的文檔是第一種結構,你想找到一個值爲「hi」的子文檔,但不知道密鑰是152,無法做到這一點。使用第二個文檔結構,您可以輕鬆查詢{「groups.name」:「hi」}。

欲瞭解更多信息,查詢嵌入對象,請參見「點表示法(把手伸進對象)」 http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29 和「價值嵌入對象」的「高級查詢」的部分中的「數組中的價值」的文件文檔也很有用: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray

對於{'groups.id':1}上的索引,將爲每個文檔中每個「groups」數組中的每個「id」鍵創建一個索引條目。使用「組」索引時,每個文檔只會創建一個索引條目。

如果您有第二類文檔和組的索引,您的查詢必須匹配整個子文檔才能使用索引。例如,鑑於該文件:

{ "_id" : 1, "groups" : [ { "id" : 152, "name" : "hi" }, { "id" : 111, "name" : "group2" } ] } 

查詢

db.<collectionName>.find({groups:{ "id" : 152, "name" : "hi" }}) 

會利用索引,但查詢

db.<collectionName>.find({"groups":{$elemMatch:{name:"hi"}}}) 

db.<collectionName>.find({"groups.name":"hi"}) 

不會。

您創建的索引應取決於您最常用的查詢。

您可以嘗試使用.explain()命令查詢您正在使用的索引(如果有)。 http://www.mongodb.org/display/DOCS/Explain第一行「光標」會告訴你正在使用哪個索引。 「光標」:「BasicCursor」表示正在執行完整收集掃描。

有相應文件,索引信息 http://www.mongodb.org/display/DOCS/Indexes

「索引數組元素」上面的鏈接的標題爲「Multikeys」對文檔部分: http://www.mongodb.org/display/DOCS/Multikeys

希望這會提高你的瞭解如何查詢嵌入式文檔以及如何使用索引。如果您有任何後續問題,請告訴我們!

+0

這是一個很好的答案,但前兩個鏈接被打破。我一直在尋找,我無法在網上找到他們的新位置。任何幫助? – portforwardpodcast 2014-01-04 05:46:25

+0

嗨,通過閱讀你的迴應,我想知道是否索引將用於查詢像'db。 .find({「groups」:{$ elemMatch:{「id」:152}}})' – 2016-09-16 10:44:14