服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - MongoDB - MongoDB 游标详解及实例代码

MongoDB 游标详解及实例代码

2020-05-11 16:33MongoDB教程网 MongoDB

这篇文章主要介绍了 MongoDB 游标详解及实例代码的相关资料,需要的朋友可以参考下

 MongoDB 游标详解

MongoDB中的游标与关系型数据库中的游标在功能上大同小异。游标相当于C语言的指针,可以定位到某条记录,在MongoDB中,则是文档。因此在mongoDB中游标也有定义,声明, 打开,读取,关闭这么个过程。客户端通过游标,能够实现对最终结果进行有效的控制,诸如限制结果数量,跳过部分结果或根据任意键按任意顺序的组合对结果进行各种排序等。下文是针对MongoDB游标的具体介绍。

一、mongoDB游标介绍

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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()

二、当前环境及数据准备

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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输出游标结果集

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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输出游标结果集

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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()进行迭代

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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()将游标迭代文档返回到一个数组,然后通过数组下标方式进行访问。

    该方法将所有由游标返回的文档装载进内存。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//如下示例,将游标返回的内容传递到数组,然后使用 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"
 }

六、调整游标迭代次数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//设置迭代显示的次数,如下设置为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

七、查看游标度量信息

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
可以通过db.serverStatus()查看游标状态相关的信息,这些信息通常包括
     从服务器上次启动之后游标超时的数量
     自定义游标超时的数量
     游标打开后已经pinned的数量
     打开游标的总数目
 //如下查询本机游标的信息   
 repSetTest:PRIMARY> db.serverStatus().metrics.cursor
 {
     "timedOut" : NumberLong(2),
     "open" : {
         "noTimeout" : NumberLong(0),
         "pinned" : NumberLong(0),
         "total" : NumberLong(2)
     }
 }

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

延伸 · 阅读

精彩推荐
  • MongoDBMongodb如何开启用户访问控制详解

    Mongodb如何开启用户访问控制详解

    默认启动 MongoDB 服务时没有任何参数,可以对数据库任意操 作,而且可以远程访问数据库,所以推荐开发阶段可以不设置任何参数,但对于生产环境还是要...

    不争5402020-05-10
  • MongoDB将MongoDB加入到Windows的本地服务项的方法

    将MongoDB加入到Windows的本地服务项的方法

    下面主要针对MongoDB在Windows下加入本地服务项做一些简单的分享。以方便刚接触MongoDB并在Windows环境下进行开发的同学 ...

    MongoDB教程网3012020-04-28
  • MongoDBMongoDB分片测试

    MongoDB分片测试

    分片是mongoDB扩展的一种方式。分片分割一个collection并将不同的部分存储在不同的机器上,本文给大家介绍MongoDB分片测试,需要的朋友参考下吧 ...

    我思,故我在5532020-05-05
  • MongoDBMongoDB 简单入门教程(安装、基本概念、创建用户)

    MongoDB 简单入门教程(安装、基本概念、创建用户)

    这篇文章主要介绍了MongoDB 简单入门教程(安装、基本概念、创建用户)的相关资料,帮助大家更好的理解和学习使用MongoDB数据库,感兴趣的朋友可以了解下...

    AsiaYe6352021-05-10
  • MongoDBMongoDB简单操作示例【连接、增删改查等】

    MongoDB简单操作示例【连接、增删改查等】

    这篇文章主要介绍了MongoDB简单操作,涉及命令行窗口下使用MongoDB进行简单的连接、增删改查等相关操作技巧,需要的朋友可以参考下 ...

    tinyphp2982020-05-23
  • MongoDBMongoDB 学习笔记

    MongoDB 学习笔记

    最近在学习MongoDB,小结一下,主要都是一些基础知识,需要的朋友可以参考下 ...

    服务器之家3412020-04-25
  • MongoDBMongodb数据库误删后的恢复方法(两种)

    Mongodb数据库误删后的恢复方法(两种)

    本文给大家分享两种方法来实现Mongodb数据库误删后的恢复,每种方法给大家介绍的都非常详细,需要的朋友参考下吧 ...

    fyg05249922020-05-18
  • MongoDBMongo服务重启异常问题的处理方法

    Mongo服务重启异常问题的处理方法

    这篇文章主要给大家介绍了关于Mongo服务重启异常问题的处理方法,这个问题其实还是挺常见的,通过此文学习处理方法,以后遇到了就不会措手不及的,需要的...

    Leafage11842021-08-24