一、简单介绍
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假设没有分配给一个使用varkeyword的变量迭代数据时,光标自己主动迭代前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()将运行很多其它的操作来获取下一批。
MongoDBserver返回的查询结果, 当调用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)
对于包含一个没有索引的排序操作的查询,server必须在返回不论什么结果之前将全部的文档载入到内存中来进行排序。
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})
四、游标的说明
默认情况下,server将自己主动关闭该游标10分钟后闲置或client遍历完结果的游标。须要手动关闭游标或清除游标是,能够在查询中使用光标指定noTimeout标记。
通过 cursor.addOption()。通过这种方法,如以下的样例:
>var cursor = db.items.find().addOption(DBQuery.Option.noTimeout);
能够查看游标信息:
(1) 打开的游标的总数
(2)当前client使用的游标大小
(3)自上次又一次启动server的超时游标数量
我们能够查看,了解游标使用情况
如以下的样例:
>db.serverStatus().metrics.cursor