2013-04-04 21 views
1

可能這是一個愚蠢的問題,但無論如何,我有疑問。爲什麼MongoDB是回到1760個文檔時,我有:PHP - mongodb客戶端 - 跳過並限制使用

請看一看這個查詢:

db.posts.find({ "blog": "myblog", 
       "post_author_id": 649, 
       "shares.total": { "$gt": 0 } }) 
     .limit(10) 
     .skip(1750) 
     .sort({ "shares.total": -1, "tstamp_published": -1 }); 

其實我看到到MongoDB的探查此報告:

mongos> db.system.profile.find({ nreturned : { $gt : 1000 } }).limit(10).sort({ millis : 1 }).pretty(); 
{ 
    "ts" : ISODate("2013-04-04T13:28:08.906Z"), 
    "op" : "query", 
    "ns" : "mydb.posts", 
    "query" : { 
     "$query" : { 
      "blog" : "myblog", 
      "post_author_id" : 649, 
      "shares.total" : { 
       "$gt" : 0 
      } 
     }, 
     "$orderby" : { 
      "shares.total" : -1, 
      "tstamp_published" : -1 
     } 
    }, 
    "ntoreturn" : 1760, 
    "nscanned" : 12242, 
    "scanAndOrder" : true, 
    "nreturned" : 1760, 
    "responseLength" : 7030522, 
    "millis" : 126, 
    "client" : "10.0.232.69", 
    "user" : "" 
} 

現在的問題是明確要求跳過1750?

這是我當前的Mongodb版本,在羣集/分片中。

mongos> db.runCommand("buildInfo") 
{ 
    "version" : "2.0.2", 
    "gitVersion" : "514b122d308928517f5841888ceaa4246a7f18e3", 
    "sysInfo" : "Linux bs-linux64.10gen.cc 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_41", 
    "versionArray" : [ 
     2, 
     0, 
     2, 
     0 
    ], 
    "bits" : 64, 
    "debug" : false, 
    "maxBsonObjectSize" : 16777216, 
    "ok" : 1 
} 

回答

0

我想你已經打了靶心,我認爲這就是爲什麼MongoDB的文件要求我們避免大的跳躍http://docs.mongodb.org/manual/reference/method/cursor.skip/原因。請看看這裏它會回答你的結果。使用其他一些與$ gt操作符一起使用的鍵會快得多。就像頁面1中最後一個鍵的日期時間戳一樣,然後在日期時間使用$ get。

的cursor.skip()方法,因爲它要求服務器從集合或索引的開始走才能偏移或開始返回結果

+0

我不能使用Datetime,因爲它是一個博客。當新職位發佈時,所有現有職位,其Datetime只是「轉移」。 Evene如果我直接去第200頁我不知道第一篇文章的日期時間。 – freedev 2013-04-05 15:23:39

1
之前跳過位置往往是昂貴的

現在的問題是:爲什麼當我明確要求跳過1750時,mongodb返回1760個文檔?

由於服務器側skip()正是如此:它遍歷第一1750分的結果,然後以上(根據限制)10得到。

正如@devesh所說,這就是爲什麼非常大的分頁應該避免,因爲MongoDB沒有有效使用skip()limit()的索引。