MongoDB:16-MongoDB-索引陣列欄位和索引子文件欄位
阿新 • • 發佈:2019-02-01
MongoDB允許深入文件內部,對巢狀欄位和陣列建立索引;
巢狀物件和陣列欄位可以和複合索引中的頂級欄位一起使用,多數情況下與“正常”索引欄位的行為也是一致的。
考慮以下文件集合(user ):
MongoDB允許深入文件內部,對巢狀欄位和陣列建立索引;
巢狀物件和陣列欄位可以和複合索引中的頂級欄位一起使用,多數情況下與“正常”索引欄位的行為也是一致的。
考慮以下文件集合(user ):
db.user.insertMany(
[
{
"address":{
"province":"HeNan",
"city":"ZhengZhou",
"pincode":"123"
},
"tags":[
"music",
"cricket",
"blogs"
],
"name":"fly"
},
{
"address":{
"province":"HeBei",
"city":"HanDan",
"pincode"
:"234"},
"tags":[
"music",
"basket",
"blogs"
],
"name":"chen"
},
{
"address":{
"province":"ChongQing",
"city":"ChongQing",
"pincode":"456"
},
"tags":[
"music",
"writing",
"running"
],
"name":"wang"
}
]
)
以上文件包含了 address 子文件和 tags 陣列。
索引陣列欄位
- 假設我們基於標籤來檢索使用者,為此我們需要對集合中的陣列 tags 建立索引。
- 在陣列中建立索引,需要對陣列中的每個欄位依次建立索引
- 使用以下命令建立陣列索引:
db.user.ensureIndex({"tags":1})
- 建立索引後,我們可以這樣檢索集合的 tags 欄位:
db.user.find({tags:"music"})
- 為了驗證我們使用使用了索引,可以使用 explain 命令:
db.user.find({tags:"music"}).explain()
- 執行結果
/* 1 */
{
"queryPlanner":{
"plannerVersion":1,
"namespace":"mongotest.user",
"indexFilterSet":false,
"parsedQuery":{
"tags":{
"$eq":"music"
}
},
"winningPlan":{
"stage":"FETCH",
"inputStage":{
"stage":"IXSCAN",
"keyPattern":{
"tags":1.0
},
"indexName":"tags_1",
"isMultiKey":true,
"multiKeyPaths":{
"tags":[
"tags"
]
},
"isUnique":false,
"isSparse":false,
"isPartial":false,
"indexVersion":2,
"direction":"forward",
"indexBounds":{
"tags":[
"[\"music\", \"music\"]"
]
}
}
},
"rejectedPlans":[]
},
"serverInfo":{
"host":"kf-PC",
"port":27017,
"version":"3.4.9",
"gitVersion":"876ebee8c7dd0e2d992f36a848ff4dc50ee6603e"
},
"ok":1.0
}
- 以上命令執行結果中會顯示 "stage":"FETCH",,則表示已經使用了索引。
stage的型別的意義
mongodb的文件中列出了前4種類型,還有一些沒有列出來,但是會比較常見,這裡一併解釋一下。
COLLSCAN :全表掃描
IXSCAN:索引掃描
FETCH::根據索引去檢索指定document
SHARD_MERGE:各個分片返回資料進行merge
SORT:表明在記憶體中進行了排序(與前期版本的scanAndOrder:true一致)
SORT_MERGE:表明在記憶體中進行了排序後再合併
LIMIT:使用limit限制返回數
SKIP:使用skip進行跳過
IDHACK:針對_id進行查詢
SHARDING_FILTER:通過mongos對分片資料進行查詢
COUNT:利用db.coll.count()之類進行count運算
COUNTSCAN:count不使用用Index進行count時的stage返回
COUNT_SCAN:count使用了Index進行count時的stage返回
SUBPLA:未使用到索引的$or查詢的stage返回
TEXT:使用全文索引進行查詢時候的stage返回
附:explain查詢結果解析官方文件:
https://docs.mongodb.org/v3.0/reference/explain-results/
陣列上的索引
(1)可以看得出在陣列欄位上建立索引的代價比較大,因為每次的刪除,更新都會對每一個索引進行重新整理,太消耗伺服器的資源;
(2)可以針對陣列欄位中的某一個元素做具體的單獨索引,減少索引的數量;
- 例如,在陣列欄位