2015-05-26 419 views
1

我有一個MongoDB的版本3.0.3收集其中包含的文件有2場:MongoDB中不使用多鍵索引

  • 一個數字長ID
  • 60個數字雙打的數組。

我在數組上建立了一個多鍵索引,並通過使用getIndexInfo()方法確認索引存在並且是多鍵。但是,當我查詢數組中兩個特定字段的交集時,Mongo不使用此索引,儘管集合中有1,000,000個文檔。我可以從explain()方法的輸出中看到這一點。更奇怪的是,當我指定使用hint索引時,Mongo遍歷所有1,000,000個文檔和60,000,000個索引條目,我在explain()的輸出中看到這些條目。

我建設用下面的代碼查詢:

BasicDBObject q2 = new BasicDBObject("array.0",new BasicDBObject("$lt",1000.0)); 
BasicDBObject q1 = new BasicDBObject("array.1",new BasicDBObject("$gte",800.0)); 
BasicDBObject q_and = new BasicDBObject("$and",Arrays.asList(q1,q2)); 
dbo = collection.find(q_and).explain(); 

有什麼想法?

在此先感謝您的幫助。

在答覆爲解釋輸出請求:

不指定一個提示,解釋輸出如下:

{ "queryPlanner" : 
{ "plannerVersion" : 1 , "namespace" : "local.TestArrays" , "indexFilterSet" : false , "parsedQuery" : 
{ "$and" : [ 
{ "array.0" : 
{ "$lt" : 1000.0 
} 
} , 
{ "array.1" : 
{ "$gte" : 800.0 
} 
}] 
} , "winningPlan" : 
{ "stage" : "COLLSCAN" , "filter" : 
{ "$and" : [ 
{ "array.0" : 
{ "$lt" : 1000.0 
} 
} , 
{ "array.1" : 
{ "$gte" : 800.0 
} 
}] 
} , "direction" : "forward" 
} , "rejectedPlans" : [ ] 
} , "executionStats" : 
{ "executionSuccess" : true , "nReturned" : 2 , "executionTimeMillis" : 2248 , "totalKeysExamined" : 0 , "totalDocsExamined" : 1000000 , "executionStages" : 
{ "stage" : "COLLSCAN" , "filter" : 
{ "$and" : [ 
{ "array.0" : 
{ "$lt" : 1000.0 
} 
} , 
{ "array.1" : 
{ "$gte" : 800.0 
} 
}] 
} , "nReturned" : 2 , "executionTimeMillisEstimate" : 2190 , "works" : 1000002 , "advanced" : 2 , "needTime" : 999999 , "needFetch" : 0 , "saveState" : 7812 , "restoreState" : 7812 , "isEOF" : 1 , "invalidates" : 0 , "direction" : "forward" , "docsExamined" : 1000000 
} , "allPlansExecution" : [ ] 
} , "serverInfo" : 
{ "host" : "NYDEVWS0005052" , "port" : 27017 , "version" : "3.0.3" , "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105" 
} 
} 

當指定索引用下面的代碼的使用方法:

collection.find(q_and).hint(「array_1」)。explain();

解釋輸出如下:

{ "queryPlanner" : 
{ "plannerVersion" : 1 , "namespace" : "local.TestArrays" , "indexFilterSet" : false , "parsedQuery" : 
{ "$and" : [ 
{ "array.0" : 
{ "$lt" : 1000.0 
} 
} , 
{ "array.1" : 
{ "$gte" : 800.0 
} 
}] 
} , "winningPlan" : 
{ "stage" : "KEEP_MUTATIONS" , "inputStage" : 
{ "stage" : "FETCH" , "filter" : 
{ "$and" : [ 
{ "array.0" : 
{ "$lt" : 1000.0 
} 
} , 
{ "array.1" : 
{ "$gte" : 800.0 
} 
}] 
} , "inputStage" : 
{ "stage" : "IXSCAN" , "keyPattern" : 
{ "array" : 1 
} , "indexName" : "array_1" , "isMultiKey" : true , "direction" : "forward" , "indexBounds" : 
{ "array" : [ "[MinKey, MaxKey]"] 
} 
} 
} 
} , "rejectedPlans" : [ ] 
} , "executionStats" : 
{ "executionSuccess" : true , "nReturned" : 2 , "executionTimeMillis" : 61401 , "totalKeysExamined" : 60000000 , "totalDocsExamined" : 1000000 , "executionStages" : 
{ "stage" : "KEEP_MUTATIONS" , "nReturned" : 2 , "executionTimeMillisEstimate" : 56570 , "works" : 60001744 , "advanced" : 2 , "needTime" : 59999998 , "needFetch" : 1743 , "saveState" : 470130 , "restoreState" : 470130 , "isEOF" : 1 , "invalidates" : 0 , "inputStage" : 
{ "stage" : "FETCH" , "filter" : 
{ "$and" : [ 
{ "array.0" : 
{ "$lt" : 1000.0 
} 
} , 
{ "array.1" : 
{ "$gte" : 800.0 
} 
}] 
} , "nReturned" : 2 , "executionTimeMillisEstimate" : 55620 , "works" : 60001744 , "advanced" : 2 , "needTime" : 59999998 , "needFetch" : 1743 , "saveState" : 470130 , "restoreState" : 470130 , "isEOF" : 1 , "invalidates" : 0 , "docsExamined" : 1000000 , "alreadyHasObj" : 0 , "inputStage" : 
{ "stage" : "IXSCAN" , "nReturned" : 1000000 , "executionTimeMillisEstimate" : 50820 , "works" : 60000000 , "advanced" : 1000000 , "needTime" : 59000000 , "needFetch" : 0 , "saveState" : 470130 , "restoreState" : 470130 , "isEOF" : 1 , "invalidates" : 0 , "keyPattern" : 
{ "array" : 1 
} , "indexName" : "array_1" , "isMultiKey" : true , "direction" : "forward" , "indexBounds" : 
{ "array" : [ "[MinKey, MaxKey]"] 
} , "keysExamined" : 60000000 , "dupsTested" : 60000000 , "dupsDropped" : 59000000 , "seenInvalidated" : 0 , "matchTested" : 0 
} 
} 
} , "allPlansExecution" : [ ] 
} , "serverInfo" : 
{ "host" : "NYDEVWS0005052" , "port" : 27017 , "version" : "3.0.3" , "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105" 
} 
} 
+0

你如何在java驅動中使用'hint'?而且還可以運行在蒙戈殼相同的查詢和發佈的輸出'解釋()'? – bagrat

+0

這說明,當我不指定提示的輸出: –

+0

請包括它在後 – bagrat

回答

0

恐怕你的問題是,你要查詢一個數組的特定元素。所以,即使你有一個數組的索引,查詢必須明確地掃描整個採集,獲取從array元素01和執行匹配。

如果您需要在特定的元素恰好運行的匹配,這是值得拉出數組並將它們作爲單獨的域,然後在其上創建索引。所以考慮一下:

{ 
    ... 
    array: [...], 
    ex_element_0: "value0", 
    ex_element_1: "value0", 
    ... 
} 
1

我誤解了多鍵索引的含義。我認爲爲陣列中的每個位置創建了一個單獨的索引。然而,在進一步的閱讀中,我看到一個單一的指數爲陣列創建爲一個文件中的所有條目被輸入到該單一指標,而不是保護陣列位置。我採納了n9code的建議,並在每個領域創建了單獨的字段和索引。這按預期工作。

+0

http://stackoverflow.com/help/someone-answers;) – bagrat