MongoDB Limit() 方法
如果你需要在MongoDB中讀取指定數量的數據記錄,可以使用MongoDB的Limit方法,limit()方法接受一個數字參數,該參數指定從MongoDB中讀取的記錄條數。
語法
limit()方法基本語法如下所示:
>db.COLLECTION_NAME.find().limit(NUMBER)
實例
集合 col 中的數據如下:
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一種創建動態交互性站點的強有力的服務器端腳本語言。", "by" : "haha", "url" : "http://www.baidu.com", "tags" : [ "php" ], "likes" : 200 }
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司於1995年5月推出的高級程序設計語言。", "by" : "haha", "url" : "http://www.baidu.com", "tags" : [ "java" ], "likes" : 150 }
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 數據庫", "by" : "haha", "url" : "http://www.baidu.com", "tags" : [ "mongodb" ], "likes" : 100 }
以下實例為顯示查詢文檔中的兩條記錄:
> db.col.find({},{"title":1,_id:0}).limit(2)
{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }
>
注:如果你們沒有指定limit()方法中的參數則顯示集合中的所有數據。
MongoDB Skip() 方法
我們除了可以使用limit()方法來讀取指定數量的數據外,還可以使用skip()方法來跳過指定數量的數據,skip方法同樣接受一個數字參數作為跳過的記錄條數。
語法
skip() 方法腳本語法格式如下:
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
實例
以下實例只會顯示第二條文檔數據
>db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "Java 教程" }
>
注:skip()方法默認參數為 0 。
db.col.find({},{"title":1,_id:0}).limit(2)
補充說明:
- 第一個 {} 放 where 條件,為空表示返回集合中所有文檔。
- 第二個 {} 指定那些列顯示和不顯示 (0表示不顯示 1表示顯示)。
想要讀取從 10 條記錄后 100 條記錄,相當於 sql 中limit (10,100)。
> db.COLLECTION_NAME.find().skip(10).limit(100)
以上實例在集合中跳過前面 10 條返回 100 條數據。
skip 和 limit 結合就能實現分頁。
補充說明skip和limit方法只適合小數據量分頁,如果是百萬級效率就會非常低,因為skip方法是一條條數據數過去的,建議使用where_limit
在查看了一些資料之后,發現所有的資料都是這樣說的:
不要輕易使用Skip來做查詢,否則數據量大了就會導致性能急劇下降,這是因為Skip是一條一條的數過來的,多了自然就慢了。
這么說Skip就要避免使用了,那么如何避免呢?首先來回顧SQL分頁的后一種時間戳分頁方案,這種利用字段的有序性質,利用查詢來取數據的方式,可以直接避免掉了大量的數數。也就是說,如果能附帶上這樣的條件那查詢效率就會提高,事實上是這樣的么?我們來驗證一下:
這里我們假設查詢第100001條數據,這條數據的Amount值是:2399927,我們來寫兩條語句分別如下:
b.test.sort({"amount":1}).skip(100000).limit(10) //183ms
db.test.find({amount:{$gt:2399927}}).sort({"amount":1}).limit(10) //53ms
結果已經附帶到注釋了,很明顯后者的性能是前者的三分之一,差距是非常大的。也印證了Skip效率差的理論。
limit(n) 是用來規定顯示的條數,而 skip(n) 是用來在符合條件的記錄中從第一個記錄跳過的條數,這兩個函數可以交換使用。
比如:find({},{age:1,_id:0}).limit(2).skip(1),在符合條件的文檔中,要顯示兩條文檔,顯示的位置從跳過第一條記錄開始。這樣不是很好理解。
如果寫成 find({},{age:1,_id:0}).skip(1).limit(2),在符合條件的文檔中,先跳過第一條文檔,然后顯示兩條文檔,這樣比較好理解。
需要注意的是,此處的skip,sort,和limit三者執行順序和位置無關,但是在聚合aggregate中使用的時候,具有管道流的特質,執行順序是按照位置關系順序執行的。
下面這個拿去命令框試,更好的體現這個 skip 到底是什么意思:
var arr = [];
for(var i=1 ; i<=20000 ; i++){
arr.push({num:i});
}
db.numbers.insert(arr);
db.numbers.find({$and:[{"num":{$lt:60}},{"num":{$gt:45}}]}).limit(7).skip(5);
find() 后出來 14 條,skip 是先將結果的前 5 條的數據清排除,然后 limit 再來限定篩選多少條。