java mongodb 查询 游标_MongoDB 游标详解及实例代码

news/2024/7/8 11:16:31

MongoDB 游标详解

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

一、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().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)

}

}

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


http://www.niftyadmin.cn/n/4388294.html

相关文章

python web自动化测试之二次封装 selenium 类

from logs.logger import Logger from selenium.common.exceptions import NoSuchElementException import time import os from selenium import webdriver """""" """二次封装 selenium 类,又称之为通用类。用于给页面类使用 &…

java程序员昵称_那些神秘的Java程序员

我们都知道程序员的工作主要就是写代码&#xff0c;这样的工作可能会给他们带来近视、秃顶等种种问题。而之前我看过一档辩论型的综艺节目&#xff0c;从中了解到&#xff0c;在北京&#xff0c;女孩们的家长最希望自己未来的女婿是个程序员。这是为什么呢&#xff1f;原来她们…

vue 中 mixins 的详细介绍

mixins(混入)就是定义了一部分公共的方法、计算属性或者钩子函数等 vue 组件中的可复用功能&#xff0c;然后混合进各个组件中使用。下面我们具体来看看怎么使用。 创建一个 demo.js 文件&#xff0c;然后 export 给外部使用 export const demoMixins {data() {return {name: …

python+selenium webui自动化测试之打开浏览器封装两种方式ini配置文件或者yaml文件

yaml文件&#xff1a;# !/usr/bin/python # -*- coding:utf-8 -*-from logs.logger import Logger from selenium import webdriver import os from configfg.read_yaml import YamlReader import timelogger Logger(logger"BrowserEngine").get_log()# 浏览器引擎类…

uni-app 微信小程序实现发送给朋友分享功能

我们在用 uni-app 开发微信小程序时&#xff0c;我们有时需要分享功能&#xff0c;uni-app 中只要在需要分享的页面的 js 中定义了 onShareAppMessage(和 onLoad 等生命周期函数同级)&#xff0c;就能实现 发送给朋友 微信小程序的分享功能。但是如果每个需要分享的页面都写一个…

mysql redis 一致性_redis与Mysql的数据一致性

为了减少db的读压力&#xff0c;加快读速度&#xff0c;系统使用cache做缓存&#xff0c;会引起cache一致性问题。因为db会有事务性导致回滚&#xff0c;而cache无法回滚&#xff0c;会导致脏数据。一般情况下&#xff0c;我们会在保存数据时&#xff0c;先穿透保存到DB中&…

事件监听器 java_java事件与监听器

在java开发中&#xff0c;事件的处理非常重要。比如在swing编程里&#xff0c;若要实现当点击按钮、文本框、移动鼠标、按下键盘就执行相应的操作&#xff0c;就要用到事件与监听器。这个过程可以分解为事件源产生某个获某些事件&#xff0c;添加在这个事件源的监听器会自动根据…

vue 中 style 的私有作用域 scoped 和深度作用选择器及 /deep/ 用法

前言 我们在用 vue 开发项目时&#xff0c;在给当前组件中的元素设置样式&#xff0c;为了不污染全局样式&#xff0c;一般会在当前组件的 <style> 标签中增加 scoped 属性&#xff0c;表明 CSS 只作用于当前组件中的元素。 实现原理 按 vue 官方解释&#xff0c;scoped …