学习MongoDB 六: MongoDB查询(游标操作、游标信息)(三)
一、简介
db.collection.find()可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段。并返回到匹配文档的游标,可以随意修改查询限制、跳跃、和排序顺序的功能。
二、db.collection.findOne ()
db.collection. findOne ()返回满足指定查询条件的文档。如果多个文档满足查询,该方法返回第一个文档,根据自然顺序返回文件在磁盘上的顺序,在覆盖的集合中,自然顺序与插入顺序相同。
语法:
db.collection.findOne(query, projection)
|
参数 |
类型 |
描述 |
|
query |
document |
可选. 使用查询操作符指定查询条件 |
|
projection |
document |
指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段 |
Projection语法:
{ field1: <boolean>, field2: <boolean> ... }
说明:
1或者true表示返回字段
0或者false表示不返回该字段
先插入数据
- >db. orders.insert([
- {
- "onumber" : "001",
- "date" : "2015-07-02",
- "cname" : "zcy1",
- "items" :[ {
- "ino" : "001",
- "quantity" :2,
- "price" : 4.0
- },{
- "ino" : "002",
- "quantity" : 4,
- "price" : 6.0
- }
- ]
- },{
- "onumber" : "002",
- "date" : "2015-07-02",
- "cname" : "zcy2",
- "items" :[ {
- "ino" : "001",
- "quantity" :2,
- "price" : 4.0
- },{
- "ino" : "002",
- "quantity" :6,
- "price" : 6.0
- }
- ]
- }
- ])
我们用db.orders.find()查询时返回多条记录
>db.orders.find({"date":"2015-07-02"})
我们执行db.orders.findOne()时,只返回第一条记录
例子:
<span style="font-size:18px;"> >db.orders.findOne({"date":"2015-07-02"})</span>
二、游标的遍历
db.collection.find()可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段。并返回到匹配文档的游标,可以随意修改查询限制、跳跃、和排序顺序的功能。
1、我们先通过javascript脚本向集合中填充10000条文档,然后执行db.collection.find()执行查询文档
- > for(var i=0;i<10000;i++){
- ...db.items.insert({"ino":i,"quantity":i});
- ... }
- WriteResult({ "nInserted" : 1 })
- > db.items.find()
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681076"), "ino" : 0,"quantity" : 0 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681077"), "ino" : 1,"quantity" : 1 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681078"), "ino" : 2,"quantity" : 2 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681079"), "ino" : 3,"quantity" : 3 }
- { "_id" : ObjectId("55a66f3c7db4e9f2ef68107a"),"ino" : 4, "quantity" : 4 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef68107b"), "ino" : 5,"quantity" : 5 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef68107c"), "ino" : 6,"quantity" : 6 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef68107d"), "ino" : 7, "quantity": 7 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef68107e"), "ino" : 8,"quantity" : 8 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef68107f"), "ino" : 9,"quantity" : 9 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681080"), "ino" : 10,"quantity" : 10 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681081"), "ino" : 11,"quantity" : 11 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681082"), "ino" : 12,"quantity" : 12 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681083"), "ino" : 13,"quantity" : 13 }
- { "_id" : ObjectId("55a66f3c7db4e9f2ef681084"),"ino" : 14, "quantity" : 14 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681085"), "ino" : 15,"quantity" : 15 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681086"), "ino" : 16,"quantity" : 16 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681087"), "ino" : 17,"quantity" : 17 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681088"), "ino" : 18,"quantity" : 18 }
- { "_id" :ObjectId("55a66f3c7db4e9f2ef681089"), "ino" : 19,"quantity" : 19 }
- Type "it" for more
- >
我们db.collection.find()执行查询文档时,发现Mongo shell如果没有分配给一个使用var关键字的变量迭代数据时,光标自动迭代前20个文档的结果返回。
输入“it”后会显示后二十条的数据。
2、你可以使用DBQuery.shellbatchsize改变迭代次数(每页就显示10条记录)
例子:
>DBQuery.shellBatchSize = 10
现在光标自动迭代前10个文档的结果返回
3、我们定义一个变量来保存这个游标
例子:
> var cursor=db.items.find()
用一个变量来保存游标,不会自动输出数据的,需要我们自己实现这个查询结果的游标进行遍历。
4、对游标进行遍历
- >var cursor=db.items.find()
- >while(cursor.hasNext()){
- var doc = cursor.next();
- printjson(doc);
- };
或者
forEach()循环遍历:
>cursor.forEach( function(doc) { printjson(doc);});
当你遍历游标到返回的批处理结束,如果有更多的结果,cursor.next()将执行更多的操作来获取下一批。
MongoDB服务器返回的查询结果, 当调用cursor.hasNext()时,MongoDB批量的大小不会超过最大BSON文档大小,然而对于大多数查询,第一批返回101文档或足够的文件超过1 MB,后续的批大小为4 MB。如果第一批是返回101个文档时,遍历完时,执行hasNext,会到数据库查询结果,直到所有结果都被返回,游标才会结关闭。
我们可以通过可以使用objsleftinbatch()方法来查看,每次返回文档数量或者大小,如下面的例子:
- >var cursor=db.items.find()
- >cursor .objsLeftInBatch();
当我们刚执行查询时,执行cursor .objsLeftInBatch();方法会显示101 ,这说明第一批返回101文档(101文档没超过1MB)
我们遍历完101个文档时,当我们执行cursor.hasNext()时,第二批会在返回101文档吗?
我们先遍历完101个文档,如下面的例子:
- >for(vari=0;i<101;i++){
- var doc = cursor.next();
- printjson(doc);
- }
这时我们迭代完第一批返回的结果,我们在执行cursor.hasNext();时,会到数据库查询下一批结果,我们objsLeftInBatch方法查看返回文档大小,如下面的例子:
- >cursor.hasNext();
- >cursor .objsLeftInBatch();
这时返回的结果是 9899, 不在是101个文档,而是4 MB,我们9899个文档没达到4MB,所有全部返回。
说明:
MongoDB使用的是内存映射存储引擎,它会把磁盘IO操作转换成内存操作,如果是读操作,内存中的数据起到缓存的作用。查询时,实现分批次返回结果,这是一个懒加载的过程,需要时才到数据库查询下一批结果,这会节省资源,不会浪费资源。
三、游标的操作
我们还可以对文档的游标,可以随意修改返回结果的限制、跳跃、和排序顺序的功能。
1. limit
limit方法是限制游标返回结果的数量,如下面例子:
>db.items.find().limit(5)
只返回结果5条文档
2.sort
sort()方法来对数据进行排序,根据指定的字段,并使用1或-1来指定排序方式是升序或降序,类似于SQL的order by。
例子:
>db.items.find({"ino":{$lt:5}}).sort({"quantity":-1})
我们查询ino小于5,并对这结果进行排序,按quantity字段降序。
我们可以指定多个字段排序,例如我们先按quantity字段降序,然后在按info升序,如下面的例子:
>db.items.find({"ino":{$lt:5}}).sort({"quantity":-1,"info":1})
我们查询ino小于5,并对这结果进行排序,按quantity字段降序
我们还可以跟limit()方法进行组合查询并对结果进行排序
例子:
>db.items.find().limit(3).sort({"quantity":1})
我们先根据quantity字段升序并返回前3条记录,发现没有键quantity(即键quantity值为null)的文档排在了前面,这是在MongoDB中,当比较不同类型值BSON,MongoDB使用以下比较顺序,从最低到最高:
- MinKey (internal type)
- Null
- Numbers (ints, longs, doubles)
- Symbol, String
- Object
- Array
- BinData
- ObjectId
- Boolean
- Date
- Timestamp
- Regular Expression
- MaxKey (internal type)
对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。
3、skip
skip方法可以跳过指定值的条数,返回剩下的条数的结果,可以跟limit()方法进行组合可以实现分页的效果。
例子:
>db.items.find().skip(10).limit(10)
跳过第10条,从第11条开始返回,只返回10条文档.
skip方法是跳过条数,而且是一条一条的跳过,如果集合比较大时(如书页数很多)skip会越来越慢, 需要更多的处理器(CPU),这会影响性能。
我们可以通过一个键值比较有顺序的来进行分页,这样就避免使用skip方法。
例子:
>db.items.find({"ino":{$lt:20,$gt:9}}).sort({"info":1})
四、游标的说明
默认情况下,服务器将自动关闭该游标10分钟后闲置或客户端遍历完结果的游标。需要手动关闭游标或清除游标是,可以在查询中使用光标指定noTimeout标记。通过 cursor.addOption(),通过这个方法,如下面的例子:
>var cursor = db.items.find().addOption(DBQuery.Option.noTimeout);
可以查看游标信息:
(1) 打开的游标的总数
(2)当前客户端使用的游标大小
(3)自上次重新启动服务器的超时游标数量
我们可以查看,了解游标使用情况
如下面的例子:
>db.serverStatus().metrics.cursor
学习MongoDB 六: MongoDB查询(游标操作、游标信息)(三)的更多相关文章
- PHP中的MySQLi扩展学习(六)MySQLI_result对象操作
在之前的文章中,我们就已经接触过 MYSQLI_result 相关的内容.它的作用其实就是一个查询的结果集.不过在 PDO 中,一般直接通过 query() 或者 PDOStatement 对象进行查 ...
- MongoDB学习笔记(六) MongoDB索引用法和效率分析
MongoDB中的索引其实类似于关系型数据库,都是为了提高查询和排序的效率的,并且实现原理也基本一致.由于集合中的键(字段)可以是普通数据类型,也可以是子文档.MongoDB可以在各种类型的键上创建索 ...
- MongoDB (六) MongoDB 集合操作
一. MongoDB 创建集合 createCollection() 方法 MongoDB db.createCollection(name, options) 是用来创建集合. 语法: 基本的 cr ...
- MySQL学习笔记六:基本DML操作
1.查询语句,语法如下: SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESUL ...
- RavenDb学习(六)查询补充特性
.延迟加载 原来的查询方式如下: IEnumerable<User> users = session .Query<User>() .Where(x => x.Name ...
- Microsoft SQL Server学习(六)--查询语句
联合查询 use student --建表 create table class_A( id int primary key, name varchar(50), sex char(50), cour ...
- MySql cmd下的学习笔记 —— 有关子查询的操作(where型,from型,exists型子查询)
先找到goods表 查询goods_id最大的商品 where型的子查询 查询goods_id最大的商品(不能用排序) 把两步写成一步,就是子查询 from型子查询 查找出每种cat_id下goods ...
- leveldb 学习记录(六)SSTable:Block操作
block结构示意图 sstable中Block 头文件如下: class Block { public: // Initialize the block with the specified con ...
- pytthon—day8 读写模式的结合、文件操作模式、with完成文本文件复制、游标操作
一.读写模式的结合 w:写指没有新建文件,有文件就清空 w=open('1.txt','w',encoding='utf-8') w.write('000\n') 在写入数据时,需要及时处理内存空间, ...
随机推荐
- JavaWeb中监听器+过滤器+拦截器区别、配置和实际应用
JavaWeb中监听器+过滤器+拦截器区别.配置和实际应用 1.前沿上一篇文章提到在web.xml中各个元素的执行顺序是这样的,context-param-->listener-->fil ...
- 2018C语言助教总结
回顾 很荣幸得到各位老师的认可,担任计科3班和4班的C语言课程助教,很感谢车老师和牛老师一学期的帮助,使得我更好的担任助教一职.我班学生59名,很愉快的与同学们度过一个美好的学期,其实作为助教同样从学 ...
- Robot Framework 安装笔记
安装python 自行搜寻安装 安装pip 进入python目录下的Scripts文件夹下,cmd,执行easy_install.exe pip 安装pywin32 pip install pywin ...
- ubuntu git生成ssh key (公钥私钥)配置github或者码云
Git是分布式的代码管理工具,远程的代码管理是基于SSH的,所以要使用远程的Git则需要SSH的配置. github的SSH配置如下: 设置Git的user name和email: git confi ...
- C#中IDisposable的用法
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...
- (8)propetry装饰器
propetry是一个内置函数,用来将一个功能伪装成一个数据属性 property将一个方法伪装成一个数据属性class People: def __init__(self,name,height,w ...
- CTF-练习平台-Misc之 猜?
六.猜? 打开图片后发现是一个半个脸被遮住的美女,再联系到题目是“猜”,答案又是一个人的名字全拼,所以熟悉的人都知道这是刘亦菲,把拼音输进去就可以啦.
- 将一个list转成json数组-晚上坐49路回去打卡
- day24 python学习 类 画元,命名空间作用域,组合,人狗大战升级
类命名空间与对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两种属性:静态属性和动态属性 静态属性就是直接在类中定义的变量 动态属性就 ...
- oracle nodejs 访问
1. 下载node-oracle网址如下: https://github.com/joeferner/node-oracle 2. 测试代码: var oracle = require('oracle ...