2011-11-18 60 views
1

我有我的想法是蒙戈一个非常简单的,简单的查询,并创建了索引:为什么我的索引只能在Mongo Query中使用?

{ "Ended" : 1, "EndDate" -1 } 

然而,当我在其上运行一个简单的查询,似乎认识到指数,但它的仍然扫描许多对象来检索数据。这是我的查询和解释结果:

PRIMARY> db.listing.find({ "Ended" : { "$ne" : true }, "EndDate" : { "$lte" : ISODate("2011-11-18T00:47:40.638Z") } }).explain(); 
{ 
     "cursor" : "BtreeCursor Ended_1_EndDate_-1 multi", 
     "nscanned" : 24508585, 
     "nscannedObjects" : 24508583, 
     "n" : 24508583, 
     "millis" : 108323, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "isMultiKey" : false, 
     "indexOnly" : false, 
     "indexBounds" : { 
       "Ended" : [ 
         [ 
           { 
             "$minElement" : 1 
           }, 
           true 
         ], 
         [ 
           true, 
           { 
             "$maxElement" : 1 
           } 
         ] 
       ], 
       "EndDate" : [ 
         [ 
           ISODate("2011-11-18T00:47:40.638Z"), 
           true 
         ] 
       ] 
     } 
} 

任何明显的想法我做错了什么?谢谢!

+0

如果你更换' “结束” 发生了:{ “$ NE”:真正}'和' “结束”:FALSE'? (或不在你的模式中工作?) – Rich

回答

0

它不会仅使用索引,因为您将通过该查询检索其他未编制索引的字段。

过去您的所有文档都有EndDate吗?当您在当前日期使用LTE时,它仍然会扫描当前日期之前的所有索引项目。它只扫描比扫描整个文档更快的索引。

如果您查询日期范围,您会看到扫描对象的数量下降。

+0

大多数都在过去。一些在未来。 – Redth

2

n字段表示您的查询是匹配的24.5M文件,其编号与nscannedObjects相同,这是正常行为。如果您不需要全部24.5M匹配的文档,则应该为查询添加其他条件。

我也看到你正在使用EndedDate: {$ne: true}。虽然这会起作用,但它会比EndedDate: false慢,所以如果该字段仅可能是truefalse,那么最好使用后者。

+0

在这一点上我不能确定结束是否存在。也许我应该运行一次查询将此字段添加到较旧的文档 – Redth

+0

是的,您应该。 '$ ne'操作是邪恶的,因为它隐含着一个'$ exists',它不能被索引。 – mnemosyn

+0

你是什么意思'$ ne'意味着'$ exists'? – dcrosta

4

索引是不是很好用$ NE或$万年queries.You将与

db.listing.find({ "Ended" : false , "EndDate" : { "$lte" : ISODate("2011-11-18T00:47:40.638Z") } }) 

的区别更好这里虽然是你将不再获取文件没有“结束”字段中,或者“结束”字段为空或其他类型。

Indexing Advice & FAQ - MongDOB

相关问题