2012-02-14 64 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