MongoDB:find({…})的真相。limit(#)

在MongoDB中, .find({...}).limit(#)真的限制了查询的数量吗?

我的意思是,当你做db.collection.find(condition) ,是不是已经浪费了计算能力来查询所有符合给定条件的结果呢? 如果是这样,那么在添加.limit()之后,只需从查询结果中.limit()不需要的元素?

非常感谢澄清这一点!

db.collection.find返回一个cursor ,而不是一个结果或类似的数组。 从文档:

find()方法“返回文档”时,该方法实际上是将cursor返回给文档。

当您迭代游标时,这些文档实际上位于该位置。 所以调用.limit告诉游标什么时候完成迭代。

更多关于游标在这里: http : //docs.mongodb.org/manual/core/cursors/#read-operations-cursors

limit()不用于后期数据过滤。 你可以用explain()来解决这个问题。 例如,我已经解雇了2个查询1)db.album.find()。explain()2)db.album.find()。limit(5).explain(); 这里是结果:

  > db.album.find().explain() { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 1000, "nscannedObjects" : 1000, "nscanned" : 1000, "nscannedObjectsAllPlans" : 1000, "nscannedAllPlans" : 1000, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 54, "nChunkSkips" : 0, "millis" : 12, "server" : "delbsinha25125:27017", "filterSet" : false } > db.album.find().limit(5).explain() { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 5, "nscannedObjects" : 5, "nscanned" : 5, "nscannedObjectsAllPlans" : 5, "nscannedAllPlans" : 5, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "server" : "delbsinha25125:27017", "filterSet" : false } 

从上面的执行计划中可以看出,有限制的只扫描了5个对象。

>

所以我试着在5天前回答这个问题,但后来发现了一些有趣的事情,我不得不去调查。

在sorting和查找之后应用限制,但是,在MongoDB(MongoDB)服务器本身的迭代结果之前不应该这样做,这意味着如果正确完成,可以使用限制来节省大量的计算能力。 Bipul的答案就是一个很好的例子,但是它并没有显示出MongoDB在这里可以实现的真正局限性。

应该注意的是,如果你使用的是最新版本的MongoDB,实际上有一个限制的错误,导致etra条目被扫描: https ://jira.mongodb.org/browse/SERVER-14712这是一件事情实际上我试图回答这个问题。

应该指出的是,上面提到的错误只会影响到使用的限制。

现在考虑@Bipuls答案没有inde使用情况下,这个故事实际上是双方,一个是他已经显示,但另一个也是如果你添加一个sorting:

 > db.rooms.find().sort({d:1}).limit(2).explain() { "clauses" : [ { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 2, "nscannedObjects" : 5, "nscanned" : 5, "scanAndOrder" : true, "indexOnly" : false, "nChunkSkips" : 0 }, { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 0, "nscannedObjects" : 0, "nscanned" : 0, "scanAndOrder" : true, "indexOnly" : false, "nChunkSkips" : 0 } ], "cursor" : "QueryOptimizerCursor", "n" : 2, "nscannedObjects" : 5, "nscanned" : 5, "nscannedObjectsAllPlans" : 5, "nscannedAllPlans" : 5, "scanAndOrder" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "server" : "ubuntu:27017", "filterSet" : false } 

集合的大小是5,你可以看到sorting后的限制已经被应用,因为它表明集合必须被完全扫描,并且由于这个查询没有inde,所以它将是一个完整的独立扫描,并且你的计算节省将会无非就是“以它的样子”。

现在,如果你添加一个inde这个是不同的,它实际上可以使用inde的顺序来停止一个完整的扫描,并且只加载你的限制,但是,由于上面的bug总是会扫描一个比所需要的多,但是这是一个独立扫描,而不是一个实际的文件被加载(取决于你的查询find()是否被覆盖)。

所以总结一下,限制使用正确的话,可以阻止MongoDB加载多余的文档,不仅可以节省工作集,而且还可以节省IO带宽。 如果你可以正确地使用限制等等,那么我肯定会推荐它。