Mongodb 基于链接时间的排序和限制问题
最近,我在玩mongo和sort/limit时遇到了一些奇怪的行为(即,意味着它们是,IMHO,违反直觉的) 假设我有以下收藏:Mongodb 基于链接时间的排序和限制问题,mongodb,Mongodb,最近,我在玩mongo和sort/limit时遇到了一些奇怪的行为(即,意味着它们是,IMHO,违反直觉的) 假设我有以下收藏: > 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")
> 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
i、 就像第二个排序应用于find返回的游标(即整个集合),然后只应用限制
我的错误是什么?我如何实现预期行为
顺便说一句:在Ubuntu11.01上运行Mongo2.0.1时,MongoDB shell会延迟计算游标,也就是说,您所做的一系列链式操作会导致一个查询被发送到服务器,使用基于链式操作的最终状态。因此,当您说“
sort({time:-1}).limit(2).sort({time:1})
”时,对sort的第二个调用将覆盖第一个调用设置的排序
为了获得期望的结果,您最好在应用程序代码中反转光标输出,特别是如果您限制为一个小的结果集(这里使用的是2)。执行此操作的确切代码取决于您使用的语言,您尚未指定该语言。将sort()
多次应用于同一查询在这里没有任何意义。有效排序将取自最后一次sort()
调用。所以
sort({time: -1}).limit(2).sort({time: 1})
与
sort({time: 1}).limit(2)
好的,托德,我的错误:)谢谢你的解释!好啊我不明白,虽然那个操作是可链接的,但它们并不是真正可组合的。另一方面,看一下,当您想要检索最后的X条消息时,这似乎是推荐的构造。但是,这个特定的答案是误导性的。千万不要把这里的任何事情都当成100%的事实,尤其是来自低声誉的用户。