MongoDB-5: 查询(游标操作、游标信息)

一、简介

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()时,只返回第一条记录

例子:

db.orders.findOne({"date":"2015-07-02"})

二、游标的遍历

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。

例子:

[sql] view plain copy

  1. >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 

原文地址:https://www.cnblogs.com/wu-chao/p/8418851.html

时间: 2024-08-05 17:34:27

MongoDB-5: 查询(游标操作、游标信息)的相关文章

MongoDB的游标操作

MongoDB的游标操作 制作人:全心全意 游标:查询的返回资源或接口,这个接口可以逐条查询 游标的声明 var cursor = db.collection名.find(); cursor.hasNext(); //判断是否有下一行 cursor.next(); //取出下一行 while循环使用游标 var cursor = db.collection名.find(); while(cursor.hasNext()){ printjson(cursor.next()) //输出json格式的

MongoDB各种查询操作详解

这篇文章主要介绍了MongoDB各种查询操作详解,包括比较查询.关联查询.数组查询等,需要的朋友可以参考下 一.find操作 MongoDB中使用find来进行查询,通过指定find的第一个参数可以实现全部和部分查询. 1.查询全部 空的查询文档{}会匹配集合的全部内容.如果不指定查询文档,默认就是{}. 2.部分查询 3.键的筛选 键的筛选是查询时只返回自己感兴趣的键值,通过指定find的第二个参数来实现.这样可以节省传输的数据量,又能节省客户端解码文档的时间和内存消耗. 查询时,数据库所关心

游标操作/pymysql事务/sql注入/索引

游标操作 import pymysql from pymysql.cursors import DictCursor # 1)建立数据库连接对象 conn conn = pymysql.connect(user='root', passwd='root', db='oldboy') # 2)通过 conn 创建操作sql的 游标对象 cursor = conn.cursor(DictCursor) # 3)编写sql交给 cursor 执行 sql = 'select * from t1' #

Linux下MongoDB的安装和操作

Mongo DB ,是目前在IT行业非常流行的一种非关系型数据库(NoSql),其灵活的数据存储方式,备受当前IT从业人员的青睐.Mongo DB很好的实现了面向对象的思想(OO思想),在Mongo DB中 每一条记录都是一个Document对象.Mongo DB最大的优势在于所有的数据持久操作都无需开发人员手动编写SQL语句,直接调用方法就可以轻松的实现CRUD操作. 一.下载mongodb 前往mongodb官网下载页面:https://www.mongodb.org/downloads下载

Mongodb 条件查询

1.1 查询出所有数据的指定键(name ,age ,country) db.persons.find({},{name:1,age:1,country:1,_id:0}) 2.查询条件 2.查询条件 2.1查询出年龄在25到27岁之间的学生 db.persons.find({age: {$gte:25,$lte:27},{_id:0,age:1}) 2.2查询出所有不是韩国籍的学生的数学成绩 db.persons.find({country:{$ne:”Korea”}},{_id:0,m:1}

Mongodb DB shell数据操作

shell命令操作语法和JavaScript很类似,其实控制台底层的查询语句都是用JavaScript脚本完成操作的. Ø 数据库 1.Help查看命令提示 help db.help(); db.yourColl.help(); db.youColl.find().help(); rs.help(); 2.切换/创建数据库 >use yourDB; 当创建一个集合(table)的时候会自动创建当前数据库 3.查询所有数据库 show dbs; 4.删除当前使用数据库 db.dropDatabas

oracle 隐式游标,显示游标,游标循环,动态SELECT语句和动态游标,异常处理和自定义异常

游标的概念:    游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁 盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库.这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率.游标有两种类型:显式游标和隐式游标.在前述程序中用到的SELECT...INTO...查询语句,一次只能从数据库中提取一行数据,对于这种 形式的查询和DML操作,系统都会使用一个隐式游标.但是如果要

MongoDB与MySQL的操作对比表及区别介绍

MongoDB与MySQL的操作对比表及区别介绍 MySQL与MongoDB都是开源的常用数据库,但是MySQL是传统的关系型数据库,MongoDB则是非关系型数据库,也叫文档型数据库,是一种NoSQL的数据库.它们各有各的优点,关键是看用在什么地方.所以我们所熟知的那些SQL(全称Structured Query Language)语句就不适用于MongoDB了,因为SQL语句是关系型数据库的标准语言. 以我们公司项目为例,在早期的项目中,都在使用关系型数据库,用过SQLServer,Orac

mysql数据库和mongodb数据库的相关操作以及两个数据库的区别

在docs命令中执行数据操作 MySQL数据库 先启动MySQL服务器  net start mysql 进入MySQL服务器MySQL -uroot -p(这里写你的数据库密码) (-P是从哪个端口进) 我第一次操作是就是因为电脑上 有 MySQL  MySQL57 MySQLla 三个服务 引起端口冲突 导致 我 找不到相应的数据 数据库操作 create database   创建数据库 show databases   显示MySQL服务上的数据库 use  数据库          使