理解MongoDB的游標有兩種維度:客戶端和服務器端。下面將從這兩方面來說明。
客戶端
find方法返回值是一個游標。可以通過游標來對最終結果進行控制。比如限制結果數量,略過某一部分,根據任意鍵按任意順序的組合對結果進行各種排序等。
創建游標
創建一個游標非常簡單,用一個局部變量接收結果集就可以了。
var cursor=db.collection.find();
迭代
要迭代結果可以使用游標的next方法。也可以使用hasNext來查看結果中是否還有下一個記錄(這里和C#集合很像)。
var obj;
while(cursor.hasNext()){
obj=cursor.next()
//do stuff
}
游標還實現了Javascript的迭代器接口,所以可以在foreach循環中使用(好熟悉):
cursor.forEach(function(x){
print(x.name)
})
在調用find時,MongoDB shell並不立即查詢數據庫,而是在等待真正開始獲取數據時才發送查詢。(類似Linq中IQueryable)。例如執行下面操作:
cursor.hasNext();
這時,查詢才會發往服務器。shell立刻獲取前100個結果或前4MB數據,這樣下次再調用hasNext或next時就不必再連接服務器取結果了。當客戶端用完第一次取得的結果時,shell會再一次連接服務器,返回下一次結果。如果繼續執行next或hasNext方法的話就會一直獲取直到把集合遍歷盡為止。
服務器端
游標生命周期
游標會消耗一定的內存和資源,一般游標遍歷完以后,或客戶端發來終止消息是,MongoDB會釋放這些資源供其他地方使用。所以要盡量保證盡快地釋放游標。
如果一個游標已經不再作用域內或超出10分沒有被使用的話,客戶端就會向服務器發送一條特殊的消息,來告訴服務器銷毀游標。這樣的話大大減少了服務器的負擔,MongoDB不用維護成千上萬個打開卻不使用的游標了。
有時這種“超時銷毀”行為是我們希望的。然而,有時我們希望延長游標的持續時間。若是如此的話,可以使用immortal函數來實現延長游標持續時間。這時要注意,一定要在迭代完結果時,主動銷毀游標,以確保游標被關閉。否則的話它會一直消耗服務器資源。