使用索引时,MongoDB排序错误

时间:2013-04-19 11:35:35

标签: mongodb

以下是查询:

db.posts.find({"project.id":5,"project.sections":6,"reading":0,"publicate":1},{"date":1}).sort({"date":-1}).limit(20)

以下是它的输出:

{ "_id" : ObjectId("51342351b6f8f38564000001"), "date" : ISODate("2013-03-05T12:38:41.731Z") }
{ "_id" : ObjectId("510ff98da80f733357000002"), "date" : ISODate("2013-02-04T19:20:25.618Z") }
{ "_id" : ObjectId("50fe4bafb6f8f3a14d000002"), "date" : ISODate("2013-01-22T08:45:16.590Z") }
{ "_id" : ObjectId("50fada8ea80f737202000039"), "date" : ISODate("2013-01-19T19:16:23.294Z") }
{ "_id" : ObjectId("50e0101fa80f73d664000002"), "date" : ISODate("2012-12-30T09:58:33.881Z") }
{ "_id" : ObjectId("50dd54d4b6f8f3923d000014"), "date" : ISODate("2012-12-30T09:52:30.993Z") }
{ "_id" : ObjectId("50ccd4a0a80f73b742000008"), "date" : ISODate("2012-12-15T20:58:18.946Z") }
{ "_id" : ObjectId("50c0e38eb6f8f32121000018"), "date" : ISODate("2012-12-06T18:35:43.098Z") }
{ "_id" : ObjectId("50314562b6f8f3f844000000"), "date" : ISODate("2012-08-22T07:06:54.822Z") }
{ "_id" : ObjectId("502012f3b6f8f3df3a000001"), "date" : ISODate("2012-08-06T19:23:10.586Z") }
{ "_id" : ObjectId("4fe6ea5ab6f8f39f59000000"), "date" : ISODate("2012-06-24T10:25:32.969Z") }
{ "_id" : ObjectId("516bbcb2a80f73a55a000000"), "date" : ISODate("2013-04-15T10:36:32.688Z") }
{ "_id" : ObjectId("516a5f62a80f733e60000000"), "date" : ISODate("2013-04-14T09:00:19.459Z") }
{ "_id" : ObjectId("515e3f2ca80f738536000003"), "date" : ISODate("2013-04-05T03:07:53.960Z") }
{ "_id" : ObjectId("5155b7c4b6f8f3ad15000001"), "date" : ISODate("2013-03-29T16:18:44.228Z") }
{ "_id" : ObjectId("514009e8a80f73f429000001"), "date" : ISODate("2013-03-29T12:31:01.898Z") }
{ "_id" : ObjectId("515566d5a80f73437d000005"), "date" : ISODate("2013-03-29T10:10:15.113Z") }
{ "_id" : ObjectId("514572cbb6f8f36525000001"), "date" : ISODate("2013-03-17T07:39:33.738Z") }
{ "_id" : ObjectId("51432a77b6f8f3024d000000"), "date" : ISODate("2013-03-15T14:07:46.648Z") }
{ "_id" : ObjectId("513d4afcb6f8f3727b000000"), "date" : ISODate("2013-03-11T17:46:21.183Z") }

正如您所看到的,订单错误,好像排序以某种奇怪的方式工作。以下是该查询的explain()输出:

"cursor" : "BtreeCursor project.id_1_project.sections_1_reading_1_publicate_1_date_-1",
"nscanned" : 929,
"nscannedObjects" : 915,
"n" : 8,
"millis" : 23,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
...}

但是,如果我禁用索引,它排序很好:

db.posts.find({"project.id":5,"project.sections":3,"reading":0,"publicate":1},{"date":1}).hint({$natural:1}).sort({"date":-1}).limit(20)

{ "_id" : ObjectId("51475ee4b6f8f3526f000004"), "date" : ISODate("2013-04-16T10:51:04.962Z") }
{ "_id" : ObjectId("5166e61fa80f73b658000001"), "date" : ISODate("2013-04-11T16:58:11.848Z") }
{ "_id" : ObjectId("514afc12a80f735162000000"), "date" : ISODate("2013-03-25T02:51:18.309Z") }
{ "_id" : ObjectId("513db351b6f8f3d601000006"), "date" : ISODate("2013-03-11T10:49:27.585Z") }
{ "_id" : ObjectId("5105ff74a80f739704000006"), "date" : ISODate("2013-02-19T11:19:57.448Z") }
{ "_id" : ObjectId("5121de84b6f8f3b20c000009"), "date" : ISODate("2013-02-18T07:58:40.779Z") }
{ "_id" : ObjectId("511dbc4ab6f8f3a550000006"), "date" : ISODate("2013-02-15T04:51:39.767Z") }
{ "_id" : ObjectId("51053aafa80f73ae74000002"), "date" : ISODate("2013-01-27T14:44:48.931Z") }
{ "_id" : ObjectId("50f1c7c4b6f8f3ed2e000003"), "date" : ISODate("2013-01-12T20:48:04.451Z") }
{ "_id" : ObjectId("50ec5111b6f8f3180e000034"), "date" : ISODate("2013-01-09T10:25:50.736Z") }
{ "_id" : ObjectId("50d36076b6f8f3707400000f"), "date" : ISODate("2012-12-20T19:14:40.412Z") }
{ "_id" : ObjectId("50b4f7b6b6f8f3d261000003"), "date" : ISODate("2012-11-27T17:52:24.675Z") }
{ "_id" : ObjectId("50a0b83eb6f8f30a74000001"), "date" : ISODate("2012-11-12T09:14:04.652Z") }
{ "_id" : ObjectId("5092746eb6f8f3c92d000000"), "date" : ISODate("2012-11-06T12:02:21.634Z") }
{ "_id" : ObjectId("50926d48b6f8f31d15000000"), "date" : ISODate("2012-11-01T13:11:40.107Z") }
{ "_id" : ObjectId("508a471cb6f8f33568000000"), "date" : ISODate("2012-10-26T19:41:50.516Z") }
{ "_id" : ObjectId("508998c5b6f8f3b977000000"), "date" : ISODate("2012-10-26T07:59:18.278Z") }
{ "_id" : ObjectId("5088c043b6f8f3442b000003"), "date" : ISODate("2012-10-25T05:08:12.372Z") }
{ "_id" : ObjectId("50857833b6f8f37770000001"), "date" : ISODate("2012-10-22T17:06:37.667Z") }
{ "_id" : ObjectId("507e2f0ab6f8f34c2d000000"), "date" : ISODate("2012-10-17T04:32:10.337Z") }

我尝试使用db.bla.reIndex()重建整个集合的索引,但它没有帮助。使用相同索引的同一集合上的所有其他查询都可以正常工作。

MongoDB 2.0.9

这种行为背后的原因是什么?

1 个答案:

答案 0 :(得分:1)

您按日期排序。然后限制输出。 MongoDB根据查询日期订购文件。然后削减前20条记录。现在,MongoDb有20条先前订购的ObjectID记录。 MongoDB显示这20个没有订单的集合。因为最后一个“限制”行创建了一组文档,并且find命令在没有排序的情况下获取集合中的任何内容。你必须链接另一个这样的排序命令:

db.posts.find({"project.id":5,"project.sections":6,"reading":0,"publicate":1},{"date":1}).sort({"date":-1}).limit(20).sort({"date":-1}))

它可能看起来很尴尬,但它实际上是自然有序的。假设您希望以自然顺序获取文档列表,但您只需要前20个具有最近日期的文档。您的查询就是这样做的。但是如果你想要按日期排序的文档列表,你应该在查询结束时再使用一个sort命令来完成它。