游標(biāo)相當(dāng)于C語言的指針,可以定位到某條記錄,在MongoDB中,則是文檔。因此在mongoDB中游標(biāo)也有定義,聲明, 打開,讀取,關(guān)閉這么個過程。客戶端通過游標(biāo),能夠?qū)崿F(xiàn)對最終結(jié)果進(jìn)行有效的控制,諸如限制結(jié)果數(shù)量,跳過部分結(jié)果或根據(jù)任意鍵按任意順序的組合對結(jié)果進(jìn)行各種排序等。 一、mongoDB游標(biāo)介紹 db.collection.find()方法返回一個游標(biāo),對于文檔的訪問,我們需要進(jìn)行游標(biāo)迭代 mongoDB的游標(biāo)與關(guān)系型數(shù)據(jù)庫SQL中的游標(biāo)類似,可以通過對游標(biāo)進(jìn)行(如限制查詢結(jié)果數(shù),跳過的結(jié)果數(shù)等)設(shè)置來控制查詢結(jié)果 游標(biāo)會消耗內(nèi)存和相關(guān)系統(tǒng)資源,游標(biāo)使用完后應(yīng)盡快釋放資源 在mongo shell中,如果返回的游標(biāo)結(jié)果集未指定給某個var定義的變量,則,游標(biāo)自動迭代20次,即輸出前20個文檔,超出20的情形則需要輸入it來翻頁 本文內(nèi)容描述手動方式來實現(xiàn)游標(biāo)迭代來訪問文檔或者是用索引迭代 聲明游標(biāo) var cursor = db.collectioName.find(query,projection); 打開游標(biāo) Cursor.hasNext() 判斷游標(biāo)是否已經(jīng)取到盡頭 讀取數(shù)據(jù) Cursor.Next() 取出游標(biāo)的下一個文檔 關(guān)閉游標(biāo) cursor.close() 此步驟可省略,通常為自動關(guān)閉,也可以顯示關(guān)閉 用while循環(huán)來遍歷游標(biāo)示例 var mycursor = db.bar.find({_id:{$lte:5}}) while(mycursor.hasNext()) { printjson(mycursor.next()); } 游標(biāo)生命周期 a、游標(biāo)完成匹配結(jié)果的迭代后,它會清除自身; b、客戶端的游標(biāo)已經(jīng)不在作用域內(nèi),驅(qū)動程序回向服務(wù)器發(fā)送一條特別的消息,讓其銷毀; c、缺省情況下,游標(biāo)在十分鐘內(nèi)沒有使用,游標(biāo)自動關(guān)閉或者客戶端已經(jīng)迭代完整個游標(biāo); d、可以通過cursor.noCursorTimeout()來定義游標(biāo)超時時間 如:var myCursor = db.users.find().noCursorTimeout() e、對于自定義超時時長的游標(biāo)可以使用cursor.close() 來關(guān)閉游標(biāo) 如:db.collection.find(<query>).close() 二、當(dāng)前環(huán)境及數(shù)據(jù)準(zhǔn)備 repSetTest:PRIMARY> db.version() 3.0.12 //創(chuàng)建包含29個文檔的集合user repSetTest:PRIMARY> for (var i=1;i<30;i++){ ... db.user.insert({"id":i,"ename":"usr"+i}); ... } WriteResult({ "nInserted" : 1 }) repSetTest:PRIMARY> db.user.count() 29 //查詢集合user上所有文檔 repSetTest:PRIMARY> db.user.find() { "_id" : ObjectId("5804d07fd974b32430ea9748"), "id" : 1, "ename" : "usr1" } { "_id" : ObjectId("5804d07fd974b32430ea9749"), "id" : 2, "ename" : "usr2" } ............................. { "_id" : ObjectId("5804d07fd974b32430ea975b"), "id" : 20, "ename" : "usr20" } Type "it" for more //上面的結(jié)果只輸出了20行,這個提示表明查看更多應(yīng)輸入it repSetTest:PRIMARY> it { "_id" : ObjectId("5804d07fd974b32430ea975c"), "id" : 21, "ename" : "usr21" } .............. { "_id" : ObjectId("5804d07fd974b32430ea9764"), "id" : 29, "ename" : "usr29" } 三、使用print輸出游標(biāo)結(jié)果集 repSetTest:PRIMARY> var myCursor = db.user.find() while (myCursor.hasNext()) { print(tojson(myCursor.next())) } { "_id" : ObjectId("5804d07fd974b32430ea9748"), "id" : 1, "ename" : "usr1" } .......... { "_id" : ObjectId("5804d07fd974b32430ea9751"), "id" : 10, "ename" : "usr10" } ................ { "_id" : ObjectId("5804d07fd974b32430ea9764"), "id" : 29, "ename" : "usr29" } //上述查詢中通過var myCursor進(jìn)行變量的定義,相當(dāng)于SQL中的declare cursor cur_name is select .. //變量 myCursor定義僅僅是定義,并不會訪問數(shù)據(jù)庫,而是在myCursor.hasNext()真正訪問數(shù)據(jù)庫 //myCursor.next()則是輸出下一條記錄,hasNext()訪問數(shù)據(jù)庫時會根據(jù)缺省游標(biāo)設(shè)定將結(jié)果讀取到本地 四、使用printjsont輸出游標(biāo)結(jié)果集 repSetTest:PRIMARY> var myCursor = db.user.find({id:{$gt:20}}) while (myCursor.hasNext()) { printjson(myCursor.next());} { "_id" : ObjectId("5804d07fd974b32430ea975c"), "id" : 21, "ename" : "usr21" } ....... { "_id" : ObjectId("5804d07fd974b32430ea9764"), "id" : 29, "ename" : "usr29" } 五、使用 forEach()進(jìn)行迭代 repSetTest:PRIMARY> var myCursor = db.user.find({id:{$gt:20}}) repSetTest:PRIMARY> myCursor.forEach(printjson); { "_id" : ObjectId("5804d07fd974b32430ea975c"), "id" : 21, "ename" : "usr21" } ................ { "_id" : ObjectId("5804d07fd974b32430ea9764"), "id" : 29, "ename" : "usr29" } 六、基于數(shù)組索引迭代 可以使用toArray()將游標(biāo)迭代文檔返回到一個數(shù)組,然后通過數(shù)組下標(biāo)方式進(jìn)行訪問。 該方法將所有由游標(biāo)返回的文檔裝載進(jìn)內(nèi)存。 //如下示例,將游標(biāo)返回的內(nèi)容傳遞到數(shù)組,然后使用 printjson (documentArray[3])輸出其中的元素 repSetTest:PRIMARY> var myCursor = db.user.find({id:{$gt:20}}) repSetTest:PRIMARY> var documentArray = myCursor.toArray(); repSetTest:PRIMARY> printjson (documentArray[3]) { "_id" : ObjectId("580d775edeb57e4d05eec0f2"), "id" : 24, //Author : Leshami "ename" : "usr24" //Blog : http://blog.csdn.net/leshami } //也可以將數(shù)組元素輸出到某個變量,然后在用printjson(myDocument)輸出這個變量,如下 repSetTest:PRIMARY> var myDocument = documentArray[3]; repSetTest:PRIMARY> printjson(myDocument) { "_id" : ObjectId("580d775edeb57e4d05eec0f2"), "id" : 24, "ename" : "usr24" } 七、調(diào)整游標(biāo)迭代次數(shù) //設(shè)置迭代顯示的次數(shù),如下設(shè)置為5 repSetTest:PRIMARY> DBQuery.shellBatchSize = 5 5 repSetTest:PRIMARY> db.user.find() { "_id" : ObjectId("5804d07fd974b32430ea9748"), "id" : 1, "ename" : "usr1" } { "_id" : ObjectId("5804d07fd974b32430ea9749"), "id" : 2, "ename" : "usr2" } { "_id" : ObjectId("5804d07fd974b32430ea974a"), "id" : 3, "ename" : "usr3" } { "_id" : ObjectId("5804d07fd974b32430ea974b"), "id" : 4, "ename" : "usr4" } { "_id" : ObjectId("5804d07fd974b32430ea974c"), "id" : 5, "ename" : "usr5" } Type "it" for more //從上面的查詢結(jié)果可知,當(dāng)輸出5個文檔就提示需要輸入it來查看更多 repSetTest:PRIMARY> it { "_id" : ObjectId("5804d07fd974b32430ea974d"), "id" : 6, "ename" : "usr6" } { "_id" : ObjectId("5804d07fd974b32430ea974e"), "id" : 7, "ename" : "usr7" } { "_id" : ObjectId("5804d07fd974b32430ea974f"), "id" : 8, "ename" : "usr8" } { "_id" : ObjectId("5804d07fd974b32430ea9750"), "id" : 9, "ename" : "usr9" } { "_id" : ObjectId("5804d07fd974b32430ea9751"), "id" : 10, "ename" : "usr10" } Type "it" for more 八、查看游標(biāo)度量信息 可以通過db.serverStatus()查看游標(biāo)狀態(tài)相關(guān)的信息,這些信息通常包括 從服務(wù)器上次啟動之后游標(biāo)超時的數(shù)量 自定義游標(biāo)超時的數(shù)量 游標(biāo)打開后已經(jīng)pinned的數(shù)量 打開游標(biāo)的總數(shù)目 //如下查詢本機(jī)游標(biāo)的信息 repSetTest:PRIMARY> db.serverStatus().metrics.cursor { "timedOut" : NumberLong(2), "open" : { "noTimeout" : NumberLong(0), "pinned" : NumberLong(0), "total" : NumberLong(2) } } |
免責(zé)聲明:本站部分文章和圖片均來自用戶投稿和網(wǎng)絡(luò)收集,旨在傳播知識,文章和圖片版權(quán)歸原作者及原出處所有,僅供學(xué)習(xí)與參考,請勿用于商業(yè)用途,如果損害了您的權(quán)利,請聯(lián)系我們及時修正或刪除。謝謝!
始終以前瞻性的眼光聚焦站長、創(chuàng)業(yè)、互聯(lián)網(wǎng)等領(lǐng)域,為您提供最新最全的互聯(lián)網(wǎng)資訊,幫助站長轉(zhuǎn)型升級,為互聯(lián)網(wǎng)創(chuàng)業(yè)者提供更加優(yōu)質(zhì)的創(chuàng)業(yè)信息和品牌營銷服務(wù),與站長一起進(jìn)步!讓互聯(lián)網(wǎng)創(chuàng)業(yè)者不再孤獨!
掃一掃,關(guān)注站長網(wǎng)微信