链接基于时间的排序和限制问题

时间:2011-12-12 12:31:25

标签: mongodb

最近我在使用mongo和sort / limit时遇到了一些奇怪的行为(即他们是恕我直言,反直觉)。

我们假设我有以下集合:

> db.fred.find()
{ "_id" : ObjectId("..."), "record" : 1, "time" : ISODate("2011-12-01T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 2, "time" : ISODate("2011-12-02T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 3, "time" : ISODate("2011-12-03T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 4, "time" : ISODate("2011-12-04T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 5, "time" : ISODate("2011-12-05T00:00:00Z") }

我想要的是按时间顺序检索“记录”之前的2条记录:4加上记录4(即记录2,记录3和记录4)

天真的我是在做一些事情:

db.fred.find({time: {$lte: ISODate("2011-12-04T00:00:00Z")}}).sort({time: -1}).limit(2).sort({time: 1})

但它没有按照我预期的方式运作:

{ "_id" : ObjectId("..."), "record" : 1, "time" : ISODate("2011-12-01T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 2, "time" : ISODate("2011-12-02T00:00:00Z") }

我认为结果将是记录2,记录3和4。

从我的回忆中,似乎2种类型在限制之前适用:

  sort({time: -1})                          => record 4, record 3, record 2, record 1
  sort({time: -1}).limit(2)                 => record 4, record 3
  sort({time: -1}).limit(2).sort({time: 1}) => record 1, record 2

,即第二种类型应用于find返回的游标(即整个集合),然后仅应用限制。

这里我的错误是什么?如何实现预期的行为?

BTW:在Ubuntu 11.01上运行mongo 2.0.1

2 个答案:

答案 0 :(得分:3)

MongoDB shell懒惰地评估游标,也就是说,你完成的一系列链接操作会导致一个查询被发送到服务器,使用基于链接操作的最终状态。因此,当您说“sort({time: -1}).limit(2).sort({time: 1})”时,第二次排序调用会覆盖第一次调用所设置的排序。

为了达到理想的效果,最好还是在应用程序代码中反转光标输出,特别是如果你限制一个小的结果集(这里你使用的是2)。这样做的确切代码取决于您使用的语言,您尚未指定。

答案 1 :(得分:3)

sort()多次应用于同一查询对此没有任何意义。有效排序将从最后sort()次呼叫中获取。所以

sort({time: -1}).limit(2).sort({time: 1})

相同
sort({time: 1}).limit(2)