濮阳杆衣贸易有限公司

主頁 > 知識庫 > MongoDB中游標(biāo)的深入學(xué)習(xí)

MongoDB中游標(biāo)的深入學(xué)習(xí)

熱門標(biāo)簽:智能電銷機(jī)器人銷售話術(shù) 沈陽營銷電銷機(jī)器人招商 南京400電話怎樣辦理 徐州ai電銷機(jī)器人原理 兗州電話外呼營銷系統(tǒng) 企業(yè)智能外呼系統(tǒng)價格多少 機(jī)器人外呼系統(tǒng)軟件存在問題 高德地圖標(biāo)注商戶位置 福州電銷機(jī)器人源代碼

前言

MongoDB中的游標(biāo)與關(guān)系型數(shù)據(jù)庫中的游標(biāo)在功能上大同小異。游標(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)行各種排序等。

通俗的說,游標(biāo)不是查詢結(jié)果,可以理解為數(shù)據(jù)在遍歷過程中的內(nèi)部指針,其返回的是一個資源,或者說數(shù)據(jù)讀取接口.

客戶端通過對游標(biāo)進(jìn)行一些設(shè)置就能對查詢結(jié)果進(jìn)行有效地控制,如可以限制查詢得到的結(jié)果數(shù)量、跳過部分結(jié)果、或?qū)Y(jié)果集按任意鍵進(jìn)行排序等!

直接對一個集合調(diào)用find()方法時,我們會發(fā)現(xiàn),如果查詢結(jié)果超過二十條,只會返回二十條的結(jié)果,這是因?yàn)镸ongodb會自動遞歸find() 返回的游標(biāo)。

下文是針對MongoDB游標(biāo)的具體介紹。

一、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)容描述手動方式來實(shí)現(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;i30;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)
 }
 }

總結(jié)

以上就是關(guān)于MongoDB游標(biāo)的全部內(nèi)容了,希望本文的內(nèi)容對大家學(xué)習(xí)或者使用MongoDB的時候能帶來一定的幫助,如果有疑問大家可以留言交流。

您可能感興趣的文章:
  • mongodb數(shù)據(jù)庫游標(biāo)的使用淺析
  • MongoDB 游標(biāo)詳解及實(shí)例代碼
  • MongoDB入門教程之聚合和游標(biāo)操作介紹
  • MongoDB游標(biāo)超時問題的4種解決方法

標(biāo)簽:邯鄲 昭通 景德鎮(zhèn) 鶴崗 大理 本溪 丹東 吉安

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MongoDB中游標(biāo)的深入學(xué)習(xí)》,本文關(guān)鍵詞  MongoDB,中游,標(biāo)的,深入,學(xué)習(xí),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MongoDB中游標(biāo)的深入學(xué)習(xí)》相關(guān)的同類信息!
  • 本頁收集關(guān)于MongoDB中游標(biāo)的深入學(xué)習(xí)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    五峰| 康乐县| 马尔康县| 鄱阳县| 新和县| 青海省| 长泰县| 丰县| 望江县| 莱阳市| 银川市| 陆丰市| 岳池县| 浦城县| 澎湖县| 涡阳县| 牙克石市| 阳东县| 定西市| 普兰店市| 灵宝市| 黑水县| 台湾省| 焉耆| 鹤壁市| 手机| 三河市| 灵武市| 精河县| 广河县| 丰宁| 长寿区| 马龙县| 年辖:市辖区| 尤溪县| 湾仔区| 汕尾市| 杨浦区| 扎囊县| 桃园县| 太湖县|