一、简介

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表示不返回该字段

先插入数据

  1. >db. orders.insert([
  2. {
  3. "onumber" : "001",
  4. "date" : "2015-07-02",
  5. "cname" : "zcy1",
  6. "items" :[ {
  7. "ino" : "001",
  8. "quantity" :2,
  9. "price" : 4.0
  10. },{
  11. "ino" : "002",
  12. "quantity" : 4,
  13. "price" : 6.0
  14. }
  15. ]
  16. },{
  17. "onumber" : "002",
  18. "date" : "2015-07-02",
  19. "cname" : "zcy2",
  20. "items" :[ {
  21. "ino" : "001",
  22. "quantity" :2,
  23. "price" : 4.0
  24. },{
  25. "ino" : "002",
  26. "quantity" :6,
  27. "price" : 6.0
  28. }
  29. ]
  30. }
  31. ])

我们用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()执行查询文档

  1. > for(var i=0;i<10000;i++){
  2. ...db.items.insert({"ino":i,"quantity":i});
  3. ... }
  4. WriteResult({ "nInserted" : 1 })
  5. > db.items.find()
  6. { "_id" :ObjectId("55a66f3c7db4e9f2ef681076"), "ino" : 0,"quantity" : 0 }
  7. { "_id" :ObjectId("55a66f3c7db4e9f2ef681077"), "ino" : 1,"quantity" : 1 }
  8. { "_id" :ObjectId("55a66f3c7db4e9f2ef681078"), "ino" : 2,"quantity" : 2 }
  9. { "_id" :ObjectId("55a66f3c7db4e9f2ef681079"), "ino" : 3,"quantity" : 3 }
  10. { "_id" : ObjectId("55a66f3c7db4e9f2ef68107a"),"ino" : 4, "quantity" : 4 }
  11. { "_id" :ObjectId("55a66f3c7db4e9f2ef68107b"), "ino" : 5,"quantity" : 5 }
  12. { "_id" :ObjectId("55a66f3c7db4e9f2ef68107c"), "ino" : 6,"quantity" : 6 }
  13. { "_id" :ObjectId("55a66f3c7db4e9f2ef68107d"), "ino" : 7, "quantity": 7 }
  14. { "_id" :ObjectId("55a66f3c7db4e9f2ef68107e"), "ino" : 8,"quantity" : 8 }
  15. { "_id" :ObjectId("55a66f3c7db4e9f2ef68107f"), "ino" : 9,"quantity" : 9 }
  16. { "_id" :ObjectId("55a66f3c7db4e9f2ef681080"), "ino" : 10,"quantity" : 10 }
  17. { "_id" :ObjectId("55a66f3c7db4e9f2ef681081"), "ino" : 11,"quantity" : 11 }
  18. { "_id" :ObjectId("55a66f3c7db4e9f2ef681082"), "ino" : 12,"quantity" : 12 }
  19. { "_id" :ObjectId("55a66f3c7db4e9f2ef681083"), "ino" : 13,"quantity" : 13 }
  20. { "_id" : ObjectId("55a66f3c7db4e9f2ef681084"),"ino" : 14, "quantity" : 14 }
  21. { "_id" :ObjectId("55a66f3c7db4e9f2ef681085"), "ino" : 15,"quantity" : 15 }
  22. { "_id" :ObjectId("55a66f3c7db4e9f2ef681086"), "ino" : 16,"quantity" : 16 }
  23. { "_id" :ObjectId("55a66f3c7db4e9f2ef681087"), "ino" : 17,"quantity" : 17 }
  24. { "_id" :ObjectId("55a66f3c7db4e9f2ef681088"), "ino" : 18,"quantity" : 18 }
  25. { "_id" :ObjectId("55a66f3c7db4e9f2ef681089"), "ino" : 19,"quantity" : 19 }
  26. Type "it" for more
  27. >

我们db.collection.find()执行查询文档时,发现Mongo shell如果没有分配给一个使用var关键字的变量迭代数据时,光标自动迭代前20个文档的结果返回。

输入“it”后会显示后二十条的数据。

   2、你可以使用DBQuery.shellbatchsize改变迭代次数(每页就显示10条记录)

例子:

     >DBQuery.shellBatchSize = 10

现在光标自动迭代前10个文档的结果返回

   3、我们定义一个变量来保存这个游标

例子:

      > var cursor=db.items.find()

用一个变量来保存游标,不会自动输出数据的,需要我们自己实现这个查询结果的游标进行遍历。

   4、对游标进行遍历

  1. >var cursor=db.items.find()
  2. >while(cursor.hasNext()){
  3. var doc = cursor.next();
  4. printjson(doc);
  5. };

或者

forEach()循环遍历:

   >cursor.forEach( function(doc) { printjson(doc);});

当你遍历游标到返回的批处理结束,如果有更多的结果,cursor.next()将执行更多的操作来获取下一批。

MongoDB服务器返回的查询结果, 当调用cursor.hasNext()时,MongoDB批量的大小不会超过最大BSON文档大小,然而对于大多数查询,第一批返回101文档或足够的文件超过1 MB,后续的批大小为4 MB。如果第一批是返回101个文档时,遍历完时,执行hasNext,会到数据库查询结果,直到所有结果都被返回,游标才会结关闭。

我们可以通过可以使用objsleftinbatch()方法来查看,每次返回文档数量或者大小,如下面的例子:

  1. >var cursor=db.items.find()
  2. >cursor .objsLeftInBatch();

当我们刚执行查询时,执行cursor .objsLeftInBatch();方法会显示101 ,这说明第一批返回101文档(101文档没超过1MB)

我们遍历完101个文档时,当我们执行cursor.hasNext()时,第二批会在返回101文档吗?

我们先遍历完101个文档,如下面的例子:

  1. >for(vari=0;i<101;i++){
  2. var doc = cursor.next();
  3. printjson(doc);
  4. }

这时我们迭代完第一批返回的结果,我们在执行cursor.hasNext();时,会到数据库查询下一批结果,我们objsLeftInBatch方法查看返回文档大小,如下面的例子:

  1. >cursor.hasNext();
  2. >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使用以下比较顺序,从最低到最高:

  1. MinKey (internal type)
  2. Null
  3. Numbers (ints, longs, doubles)
  4. Symbol, String
  5. Object
  6. Array
  7. BinData
  8. ObjectId
  9. Boolean
  10. Date
  11. Timestamp
  12. Regular Expression
  13. 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查询(游标操作、游标信息)(三)的更多相关文章

  1. PHP中的MySQLi扩展学习(六)MySQLI_result对象操作

    在之前的文章中,我们就已经接触过 MYSQLI_result 相关的内容.它的作用其实就是一个查询的结果集.不过在 PDO 中,一般直接通过 query() 或者 PDOStatement 对象进行查 ...

  2. MongoDB学习笔记(六) MongoDB索引用法和效率分析

    MongoDB中的索引其实类似于关系型数据库,都是为了提高查询和排序的效率的,并且实现原理也基本一致.由于集合中的键(字段)可以是普通数据类型,也可以是子文档.MongoDB可以在各种类型的键上创建索 ...

  3. MongoDB (六) MongoDB 集合操作

    一. MongoDB 创建集合 createCollection() 方法 MongoDB db.createCollection(name, options) 是用来创建集合. 语法: 基本的 cr ...

  4. MySQL学习笔记六:基本DML操作

    1.查询语句,语法如下: SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESUL ...

  5. RavenDb学习(六)查询补充特性

    .延迟加载 原来的查询方式如下: IEnumerable<User> users = session .Query<User>() .Where(x => x.Name ...

  6. Microsoft SQL Server学习(六)--查询语句

    联合查询 use student --建表 create table class_A( id int primary key, name varchar(50), sex char(50), cour ...

  7. MySql cmd下的学习笔记 —— 有关子查询的操作(where型,from型,exists型子查询)

    先找到goods表 查询goods_id最大的商品 where型的子查询 查询goods_id最大的商品(不能用排序) 把两步写成一步,就是子查询 from型子查询 查找出每种cat_id下goods ...

  8. leveldb 学习记录(六)SSTable:Block操作

    block结构示意图 sstable中Block 头文件如下: class Block { public: // Initialize the block with the specified con ...

  9. pytthon—day8 读写模式的结合、文件操作模式、with完成文本文件复制、游标操作

    一.读写模式的结合 w:写指没有新建文件,有文件就清空 w=open('1.txt','w',encoding='utf-8') w.write('000\n') 在写入数据时,需要及时处理内存空间, ...

随机推荐

  1. 1.1.4 A+B for Input-Output Practice (V)

    A+B for Input-Output Practice (V) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...

  2. android复制包需要修改的几个地方

    1.要看什么情况,若是在同一个eclipse下,那么就需要修改包名.若不在的话,那就可以不用了. 2.这个app_name也是一样. 3.先说下情况,这是我修改好的.原本这个R的是引之前包的,必须要改 ...

  3. DoTween用法教程

    DoTween用法攻略 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享.心创 ...

  4. Windows 10中更新Anaconda和第三方包

    =============================== 作为专业的Python开发者,Anaconda包肯定很熟悉 下面总结一下Anaconda的升级和维护 步骤一: 打开cmd,切换到Ana ...

  5. hdu 2063 二分图匹配

    题意:一些女的和一些男的有好感,有好感的能一起坐过山车,问最多能组成多少对 hdu 11 页上少有的算法题,二分图匹配问题,匈牙利算法,对于每一个汉子,看和他有好感的妹子有没有配对了,没有配对过就可以 ...

  6. 【HAOI2016】食物链

    HA真是弱…… 原题: 1.食物链[问题描述]如图所示为某生态系统的食物网示意图,据图回答第1小题. 1.数一数,在这个食物网中有几条食物链( )现在给你n个物种和m条能量流动关系,求其中的食物链条数 ...

  7. python list 的查找, 搜索, 定位, 统计

    Python中是有查找功能的,四种方式:in.not in.count.index,前两种方法是保留字,后两种方式是列表的方法. 下面以a_list = ['a','b','c','hello'],为 ...

  8. leetcode:Minimum Depth of Binary Tree【Python版】

    1.类中递归调用添加self: 2.root为None,返回0 3.root不为None,root左右孩子为None,返回1 4.返回l和r最小深度,l和r初始为极大值: # Definition f ...

  9. bat根据星期启动程序

    原来公司里的由于每次开机时启动的程序比较多,所以打算使用批处理程序,这里只列举了部分.在每周一到周五的时候,开机则启动指定的应用程序,如果是周末的两天则不启动任何程序,所以做了这个脚本.你如果需要,根 ...

  10. jsp 知识点

    在JSP中很多对象是不需要创建的,如out.session等.它们可以直接使用. <% out.println(session.getId()); %>