學習mongodb,體會mongodb的每一個使用細節,歡迎閱讀威贊的文章。這是威贊發布的第90篇mongodb技術文章,歡迎瀏覽本專欄威贊發布的其他文章。如果您認為我的文章對您有幫助或者解決您的問題,歡迎在文章下面點個贊,或者關注威贊。謝謝。
在mongodb中,為集合添加單字段索引,能夠提高針對單個字段的查詢效率。但對于針對多個字段的查詢,要怎樣提高查詢效率呢?例如一個雜貨店的老板,想要通過查詢商品和剩余數量,來知道是否需要補貨。這里我們結合官方文檔,整理介紹mongodb的另一個索引類型,復合索引。
定義
復合索引是使用集合當中文檔兩個或多個字段構成的索引。索引中收集和排序了用戶指定的字段,按照用戶指定的順序,依次分組排序。
下圖展示了一個復合索引的結構。用戶使用userid正序和分數倒序建立的復合索引。在mongodb索引當中,先按照userid字母表順序正序排列,然后在每一個userid下面,分數按照倒序來排列。
在通用的查詢字段上添加索引,能夠增加索引覆蓋查詢的機會。索引覆蓋查詢是只能夠完全使用索引來執行的查詢,不需要掃描文檔數據來返回結果。
語法
db.<collection>.createIndex( {<field1>: <sortOrder>,<field2>: <sortOrder>,……<fieldN>: <sortOrder>,
})
限制
- 單個復合索引,最多包含32個字段
- 索引中字段排序影響復合索引的效率。復合索引中包含了依據用戶定義的字段順序所創建的文檔引用。
- 復合索引按照正序或倒序的順序,保存指定字段值。而這種排序順序,能夠決定查詢是否支持索引排序。
- 復合索引可以包含一個哈希索引字段
復合索引前綴查詢
索引前綴查詢表示使用索引字段中的前面部分字段來進行的索引查詢。mongodb的復合索引,支持這樣的前綴查詢。
考慮這樣的索引
{"item": 1, "location": 1, "stock": 1}
該索引當中,包含兩個索引前綴
{"item": 1}
{"item": 1, "location": 1}
則該索引,能夠支持下面的字段組合查詢
-
- item
- item + location
- item + location + stock
mongodb也可以使用這個索引支持item + stock這兩個字段的查詢。但只有item字段使用了這個索引,stock查詢條件無法使用這個索引。因為構建索引時, stock字段跟隨在location字段后。索引數據數據中,stock字段值排列在location字段的分組中。索引字段按照建立索引時字段順序解析。如果一個查詢跳過了索引前綴,則無法使用索引。如上述索引,無法支持下面幾個字段的查詢
-
- location
- stock
- location + stock
缺少了item字段,這些查詢都無法使用該索引。
特殊復合索引
復合索引能夠包含不同類型的特殊索引。索引類型的組合方式,能夠決定索引匹配文檔的方式。
下面的表格展示了包含不同特殊索引的復合索引構建行為。
復合索引構成 | 復合索引行為 |
正序索引 倒序索引 | 為包含指定字段的文檔建立索引 |
正序索引 倒序索引 地理位置索引 | 只能為包含地理位置的文檔建立索引 |
正序索引 倒序索引 文本索引 | 只能為包含文檔字段的文檔建立索引 |
應用
構建集合students并插入數據
db.students.insertMany([{"name": "Alice","gpa": 3.6,"location": { city: "Sacramento", state: "California" }},{"name": "Bob","gpa": 3.2,"location": { city: "Albany", state: "New York" }}
])
為name字段和gpa字段添加復合索引。索引中按照name字段的正序排列,gpa字段的倒序排列
db.students.createIndex({name: 1,gpa: -1
})
該索引能夠支持針對name和gpa兩個字段的查詢,也能夠支持name字段的查詢,因為name字段是該索引的索引前綴。
db.students.find({name: 'Alice',gpa: 3.6
})db.students.find({name: 'Bob'
})
該索引不支持僅包括gpa字段的查詢,如
db.students.find({ gpa: { $gt: 3.5}})
因為gpa字段,沒有在該索引的前綴當中。