2015-11-14 60 views
0

下面的文檔存儲在集合中:MongoDB的選擇錯誤的索引

"ldr": { 
    "d": NumberInt(318), 
    "w": NumberInt(46), 
    "m": NumberInt(10), 
    "pts": [ 
     { 
     "lid": ObjectId("47cc67093475061e3d95369d"), 
     "dPts": NumberLong(110), 
     "wPts": NumberLong(110), 
     "mPts": NumberLong(220), 
     "aPts": NumberLong(3340) 
     }, 
     { 
     "lid": ObjectId("56316279be4f0eda62ebfee0"), 
     "dPts": NumberInt(0), 
     "wPts": NumberInt(0), 
     "mPts": NumberInt(0), 
     "aPts": NumberInt(0) 
     } 
    ] 
    } 

我有一個收集4個指標:

ldr.pts.lid_1_ldr.d_1_ldr.pts.dPts_-1 
ldr.pts.lid_1_ldr.w_1_ldr.pts.wPts_-1 
ldr.pts.lid_1_ldr.m_1_ldr.pts.mPts_-1 
ldr.pts.lid_1_ldr.pts.aPts_-1 

我用下面的查詢:

db.my_collection.find({"ldr.pts.lid":ObjectId("47cc67093475061e3d95369d"), "ldr.w": NumberInt(46)},{"ldr":1}).sort({"ldr.pts.wPts":-1}).explain() 

注意:我已經用{ldr:1}運行了這個查詢,結果相同。

我希望上面的查詢使用以下指標:

ldr.pts.lid_1_ldr.w_1_ldr.pts.wPts_-1 

然而,這是解釋的結果:

{ 
     "cursor" : "BtreeCursor ldr.pts.lid_1_ldr.d_1_ldr.pts.dPts_-1", 
     "isMultiKey" : true, 
     "n" : 3, 
     "nscannedObjects" : 4, 
     "nscanned" : 4, 
     "nscannedObjectsAllPlans" : 16, 
     "nscannedAllPlans" : 16, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "millis" : 0, 
     "indexBounds" : { 
       "ldr.pts.lid" : [ 
         [ 
           ObjectId("47cc67093475061e3d95369d"), 
           ObjectId("47cc67093475061e3d95369d") 
         ] 
       ], 
       "ldr.d" : [ 
         [ 
           { 
             "$minElement" : 1 
           }, 
           { 
             "$maxElement" : 1 
           } 
         ] 
       ], 
       "ldr.pts.dPts" : [ 
         [ 
           { 
             "$maxElement" : 1 
           }, 
           { 
             "$minElement" : 1 
           } 
         ] 
       ] 
     }, 
     "server" : "Beast-PC:27017", 
     "filterSet" : false 
} 

正如你可以看到正在挑選的第一個索引。

我試過使用提示並提供正確的索引,但仍然導致indexOnly爲false,並且在scanAndOrder爲true。

任何想法?

+1

對數組中的字段進行排序不可能產生您期望的結果,因爲您對ldr.pts.wPts的降序排序將基於每個文檔的「wPts」值的最大值進行排序, pts'數組。這就是爲什麼你的查詢不能使用索引進行排序的根源。 – JohnnyHK

+0

感謝您的評論。它如何完美地適用於dPts和aPts索引?似乎中斷的只有周和月查詢。 –

+0

我剛剛跑了一些測試,你說得對。如果你想發表你的評論作爲答案,我會把它標記爲正確的:) –

回答

1

陣列中的一個字段排序是不可能產生你期待什麼作爲你的降序排序上ldr.pts.wPts基礎上,最大所有wPts值從每個文檔的pts陣列將排序,而不是僅僅來自匹配的pts數組元素的wPts值。

這就是爲什麼您的查詢無法使用索引進行排序的根本原因。