我使用聚合框架來分組一些數據。據觀察,當使用$ project pipeline階段時,它會以某種方式阻止跟隨$ match使用索引。 我有一個字段'時間戳'的索引,集合包含500 000條記錄。
如果我使用下面的命令和管道:
db.collection.runCommand('aggregate', {pipeline: [ { "$match" : { "timestamp" : { "$gt" : 1388425361294 , "$lt" : 1388443361294}}} ], explain: true})
執行計劃是相當多的期望是什麼,也就是4號文件掃描。 'explain'的摘錄:
"cursor" : {
"cursor" : "BtreeCursor timestamp_1",
"isMultiKey" : false,
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 4,
"nscannedObjectsAllPlans" : 4,
"nscannedAllPlans" : 4,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"timestamp" : [
[
1388425361294,
1388443361294
]
]
},
.......
但是,一旦我使用任何$ project參數,行爲就會徹底改變。下面的命令(「國家」字段可能甚至沒有任何文檔的存在,它不會使任何區別):
db.collection.runCommand('aggregate', {pipeline: [ { "$project" : { "country" : "$country"} , { "$match" : { "timestamp" : { "$gt" : 1388425361294 , "$lt" : 1388443361294}}} ], explain: true})
產生這個計劃:
"cursor" : {
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 500001,
"nscannedObjects" : 500001,
"nscanned" : 500001,
"nscannedObjectsAllPlans" : 50
"nscannedAllPlans" : 500001,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 101,
"indexBounds" : {
},
....
顯然會強制掃描集合的所有記錄,這對我來說是不可接受的。
我在使用$ project pipeline階段時錯過了一些重要的東西嗎?
非常感謝,爲了全面的解釋。 –