2012-02-14 77 views
2

我創造了周圍的幾個項目的索引用於特定查詢我做:蒙戈指數不使用

{ 
    "v" : 1, 
    "key" : { 
     "MODIFIED" : -1, 
     "state" : 1, 
     "fail" : 1, 
     "generated" : 1 
    }, 
    "ns" : "foo.bar", 
    "name" : "MODIFIED_-1_state_1_fail_1_generated" 
} 

然而,當我執行我的查詢,它不使用apear我的索引是。你能不能提供一些我做錯的事情?

謝謝!

db.foo.find( { 
    "$or": [ 
     { 
      "MODIFIED": { 
       "$gt": { 
        "sec": 1321419600, 
        "usec": 0 
       } 
      } 
     }, 
     { 
      "$or": [ 
       {"state": "ca"}, 
       {"state": "ok"} 
      ] 
     } 
    ], 
    "$and": [ 
     {"fail": {"$ne": 1}}, 
     {"generated": {"$exists": false}} 
    ] 
}).explain(); 
{ 
    "cursor" : "BasicCursor", 
    "nscanned" : 464215, 
    "nscannedObjects" : 464215, 
    "n" : 0, 
    "millis" : 7549, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 

    } 
} 

回答

7

有一個很好的理由,您的索引不能用於您的查詢,我也認爲有一些問題與查詢本身。它沒有觸及索引的原因是因爲嵌套的$或操作符的方式,但我認爲你的實際問題是對MongoDB中所有可用的運算符缺乏瞭解:

首先,你的嵌套$或者檢查狀態是「ca」還是「ok」是不必要的,並且(因爲這是你沒有擊中索引的主要原因)可以用state:{$in:["ca", "ok"]}代替,它可以完全相同。現在您的查詢是:

db.foo.find( { 
    "$or": [ 
     { 
      "MODIFIED": { 
       "$gt": { 
        "sec": 1321419600, 
        "usec": 0 
       } 
      } 
     }, 
     { 
      state:{$in:["ca", "ok"]}    
     } 
    ], 
    "$and": [ 
     {"fail": {"$ne": 1}}, 
     {"generated": {"$exists": false}} 
    ] 
}).explain(); 

它會打你的索引。你的第二個問題是,頂層的$和子句是沒有必要的。請注意0​​。該查詢不相同:

db.foo.find( { 
    "$or": [ 
     { 
      "MODIFIED": { 
       "$gt": { 
        "sec": 1321419600, 
        "usec": 0 
       } 
      } 
     }, 
     { 
      state:{$in:["ca", "ok"]}    
     } 
    ], 

    "fail": {"$ne": 1}, 
    "generated": {"$exists": false} 

}).explain(); 

仍然命中指數:

{ 
     "clauses" : [ 
       { 
         "cursor" : "BtreeCursor MODIFIED_-1_state_1_fail_1_generated_1 multi", 
         "nscanned" : 0, 
         "nscannedObjects" : 0, 
         "n" : 0, 
         "millis" : 1, 
         "nYields" : 0, 
         "nChunkSkips" : 0, 
         "isMultiKey" : false, 
         "indexOnly" : false, 
         "indexBounds" : { 
           "MODIFIED" : [ 
             [ 
               { 
                 "$maxElement" : 1 
               }, 
               { 
                 "sec" : 1321419600, 
                 "usec" : 0 
               } 
             ] 
           ], 
           "state" : [ 
             [ 
               { 
                 "$minElement" : 1 
               }, 
               { 
                 "$maxElement" : 1 
               } 
             ] 
           ], 
           "fail" : [ 
             [ 
               { 
                 "$minElement" : 1 
               }, 
               1 
             ], 
             [ 
               1, 
               { 
                 "$maxElement" : 1 
               } 
             ] 
           ], 
           "generated" : [ 
             [ 
               null, 
               null 
             ] 
           ] 
         } 
       }, 
       { 
         "cursor" : "BasicCursor", 
         "nscanned" : 0, 
         "nscannedObjects" : 0, 
         "n" : 0, 
         "millis" : 1, 
         "nYields" : 0, 
         "nChunkSkips" : 0, 
         "isMultiKey" : false, 
         "indexOnly" : false, 
         "indexBounds" : { 

         } 
       } 
     ], 
     "nscanned" : 0, 
     "nscannedObjects" : 0, 
     "n" : 0, 
     "millis" : 1 
} 

希望幫助!順便說一下,在您的複合索引中,第一個鍵的順序爲1,第二個鍵的順序爲-1,稍微更常規。請注意,-1僅用於確定相對於前一個字段的方向。

+0

謝謝你的優秀答案;以及一點教育! – Petrogad 2012-02-14 19:35:22

+0

調整,一切都很好;快多了。再次感謝你的幫助! – Petrogad 2012-02-14 19:59:27

+0

不客氣;) – 2012-02-15 09:10:45