密集索引
mongodb索引默認是密集型的。在一個有索引的集合里,每個文檔都會有對應的索引項,哪怕文檔中沒有被索引鍵也是如此。例如,給文檔的name字段建索引,而有的文檔并沒有name字段,那么name字段索引里會有null值,可以這樣查詢name為null值的文檔:db.products.find({name: null})。
稀疏索引
在稀疏索引里,只會出現(xiàn)被索引鍵有值的文檔。如果想創(chuàng)建稀疏索引,指定{sparse: true}就可以了。例如,可以像下面這樣在name上創(chuàng)建一個唯一性稀疏索引:
db.products.ensureIndex({name: 1}, {unique: true, sparse: true})
比較
兩種情況下不太適合使用默認的密集型索引:
一種是希望在并非出現(xiàn)在集合所有文檔內(nèi)的字段上增加唯一性索引時。舉例來說,你明確希望在每個產(chǎn)品的sku字段上增加唯一性索引。但是出于某些原因,假設產(chǎn)品在還未分配sku時就加入系統(tǒng)了。如果sku字段上有唯一性索引,而你希望插入多個沒有sku的產(chǎn)品,那么第一次插入會成功,但后續(xù)插入都會失敗,因為索引里已經(jīng)存在一個sku為null的項了。這種情況下密集型索引并不適合,你所需要的是稀疏索引(sparse index)。
另一種適用稀疏索引的情況:集合中大量文檔都不包含被索引鍵。例如,假設允許對電子商務網(wǎng)站進行匿名評論。這種情況下,半數(shù)評論都可能缺少user_id字段,如果那個字段上有索引,那么該索引中一半的項都會是null。出于兩個原因,這種情況的效率會很差。第一,這會增加索引的大小。第二,在添加和刪除帶null值user_id字段的文檔時也要求更新索引。
如果很少(或不會)對匿名評論進行查詢,那么可以選擇在user_id上構(gòu)建一個稀疏索引。