①是什么游标

游标不是查询结果,可以理解为数据在遍历过程中的内部指针,其返回的是一个资源,或者说数据读取接口.

客户端通过对游标进行一些设置就能对查询结果进行有效地控制,如可以限制查询得到的结果数量、跳过部分结果、或对结果集按任意键进行排序等!

直接对一个集合调用find()方法时,我们会发现,如果查询结果超过二十条,只会返回二十条的结果,这是因为Mongodb会自动递归find() 返回的游标。

②mongoDB游标介绍

db.collection.find()方法返回一个游标,对于文档的访问,我们需要进行游标迭代mongoDB的游标与关系型数据库SQL中的游标类似,可以通过对游标进行(如限制查询结果数,跳过的结果数等)设置来控制查询结果

游标会消耗内存和相关系统资源,游标使用完后应尽快释放资源

在mongo shell中,如果返回的游标结果集未指定给某个var定义的变量,则游标自动迭代20次,即输出前20个文档,超出20的情形则需要输入it来翻页

本文内容描述手动方式来实现游标迭代来访问文档或者是用索引迭代

声明游标

var cursor = db.collectioName.find(query,projection);

打开游标

Cursor.hasNext() 判断游标是否已经取到尽头

读取数据

Cursor.Next()  取出游标的下一个文档

关闭游标

cursor.close()  此步骤可省略,通常为自动关闭,也可以显示关闭

用while循环来遍历游标示例

var mycursor = db.bar.find({_id:{$lte:5}})

while(mycursor.hasNext()) {

printjson(mycursor.next());

}

游标生命周期

a、游标完成匹配结果的迭代后,它会清除自身;

b、客户端的游标已经不在作用域内,驱动程序回向服务器发送一条特别的消息,让其销毁;

c、缺省情况下,游标在十分钟内没有使用,游标自动关闭或者客户端已经迭代完整个游标;

d、可以通过cursor.noCursorTimeout()来定义游标超时时间

如:var myCursor = db.users.find().noCursorTimeout()

e、对于自定义超时时长的游标可以使用cursor.close() 来关闭游标

如:db.collection.find(<query>).close()

③当前环境及数据准备

repSetTest:PRIMARY> db.version();

3.0.12

//创建包含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  //上面的结果只输出了20行,这个提示表明查看更多应输入it

repSetTest:PRIMARY> it

{ "_id" : ObjectId("5804d07fd974b32430ea975c"), "id" : 21, "ename" : "usr21" }

..............

{ "_id" : ObjectId("5804d07fd974b32430ea9764"), "id" : 29, "ename" : "usr29" }

④使用print输出游标结果集

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进行变量的定义,相当于SQL中的declare cursor cur_name is select ..

//变量 myCursor定义仅仅是定义,并不会访问数据库,而是在myCursor.hasNext()真正访问数据库

//myCursor.next()则是输出下一条记录,hasNext()访问数据库时会根据缺省游标设定将结果读取到本地

⑤使用printjsont输出游标结果集

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()进行迭代

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"

}

⑦基于数组索引迭代

可以使用toArray()将游标迭代文档返回到一个数组,然后通过数组下标方式进行访问。该方法将所有由游标返回的文档装载进内存。

如下示例,将游标返回的内容传递到数组,然后使用 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

}

//也可以将数组元素输出到某个变量,然后在用printjson(myDocument)输出这个变量,如下

repSetTest:PRIMARY> var myDocument = documentArray[3];

repSetTest:PRIMARY> printjson(myDocument)

{

"_id" : ObjectId("580d775edeb57e4d05eec0f2"),

"id" : 24,

"ename" : "usr24"

}

⑧调整游标迭代次数

//设置迭代显示的次数,如下设置为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 //从上面的查询结果可知,当输出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

⑨查看游标度量信息

可以通过db.serverStatus()查看游标状态相关的信息,这些信息通常包括

从服务器上次启动之后游标超时的数量

自定义游标超时的数量

游标打开后已经pinned的数量

打开游标的总数目

//如下查询本机游标的信息

repSetTest:PRIMARY> db.serverStatus().metrics.cursor

{

"timedOut" : NumberLong(2),

"open" : {

"noTimeout" : NumberLong(0),

"pinned" : NumberLong(0),

"total" : NumberLong(2)

}

}

 
 
 
 
 
 
 
 
 
 
 

第12章:MongoDB-CRUD操作--文档--查询--游标详解的更多相关文章

  1. 第11章:MongoDB-CRUD操作--文档--查询

    ①语法 db.collection.find(query, projection) ②参数 query :可选,使用查询操作符指定查询条件 projection :可选,使用投影操作符指定返回的键.查 ...

  2. SpringMVC MongoDB之“基本文档查询(Query、BasicQuery)”

    一.简介 spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我 ...

  3. 第08章:MongoDB-CRUD操作--文档--删除

    ①语法 remove()  [2.6以后方法过时] deleteOne() [2.6以后官方推荐] deleteMany() [2.6以后官方推荐] db.collection.remove( < ...

  4. 第07章:MongoDB-CRUD操作--文档--创建

    ①语法 insert() save()  --有修改没有新增 insertOne() [3.2版本新增]向指定集合中插入一条文档数据 insertMany() [3.2版本新增]向指定集合中插入多条文 ...

  5. 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)

    众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...

  6. 四种生成和解析XML文档的方法详解

    众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...

  7. 第15.37节 PyQt(Python+Qt)入门学习:containers容器类部件QMdiArea多文档界面部件详解及编程开发案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 老猿在前期学习PyQt相关知识时,对每个组件的属性及方法都研 ...

  8. 大杂烩 -- 四种生成和解析XML文档的方法详解

    基础大杂烩 -- 目录 众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J DOM:在现在的Java JDK里都自带了,在xml-apis.jar包 ...

  9. 用PHP实现浏览器点击下载各种格式文档的方法详解【txt apk等等】

    [[注:其他文件想设置成下载文件,和下面介绍的方法一致]] 由于现在的浏览器已经可以识别txt文档格式,如果只给txt文档做一个文字链接的话,点击后只是打开一个新窗口显示txt文件的内容,并不能实现点 ...

随机推荐

  1. 【C】C语言中的_exit()与exit()

    _exit()和exit()主要区别是一个退出进程会清理I/O缓冲区,一个直接结束进程进入到内核中. 举例说明: #include <stdio.h> /*demo01 程序只输出 hel ...

  2. Windows 64 位 mysql 5.7.20 安装教程

    mysql 5.7以上版本包解压中没有data目录和my-default.ini和my.ini文件以及服务无法启动的解决办法以及修改初始密码的方法 mysql官网下载地址:https://dev.my ...

  3. C++ 读取文本文件内容到结构体数组中并排序

    成绩排行:从Score.txt文件读取学生信息,对其进行排序,按回答题数从大到小排,若相等,按分数从小到大排 #include<iostream> #include<fstream& ...

  4. composer 安装新包失败的原因之一

    各种方法都尝试过了,然而最大的可能就是不能访问国外的资源! 1.使用vpnFQ下载 2.修改一下composer的配置,命令如下: composer config -g repo.packagist ...

  5. WEB框架Django之ORM操作

    一 ORM的简介 MVC或者MVC框架中包括的一个重要部分就是ORM,它实现了数据模型与数据库的解耦. 即数据模型的设计不需要依赖于特定的数据库,通过简单的配置可以轻松更换数据库,这可以大大减少开发人 ...

  6. 引入flash

    调用代码 <div class="media"> <object class="main_video_box" classid="c ...

  7. Windows下PythonQt编译(vs2015+Qt5.11.2+PythonQt 3.2)

    后记: 由于自己low,没有下载罪行的python3.2导致编译上遇到种种问题,后文可以参考,建议看: <Windows7 VS2015 下编译 PythonQt3.2> https:// ...

  8. 解决织梦替换ueditor编辑器后栏目与单页无法保存内容

    织梦的默认编辑器是ckeditor,没有插入代码的功能,不够强大,就换成了百度的UEditor编辑器. 使用织梦DedeCMS百度整合UEditor编辑器时,碰到了栏目内容或者单页无法保存的问题,这个 ...

  9. mtcp的快速编译(连接)

    mtcp的快速编译 http://mos.kaist.edu/guide/config/03_build_mtcp.html 介绍DPDK中使用mtcp的文档 https://dpdksummit.c ...

  10. Luogu1501 Tree II - LCT

    Code #include<cstdio> #include<cstring> #include<algorithm> #define rd read() #def ...