find() 简介
MongoDB 中查询文档使用 find() 方法。find() 方法以非结构化的方式来显示所要查询的文档, 查询数据的语法格式如下:
>db.collection.find(query, projection)
query 为可选项,设置查询操作符指定查询条件;projection 也为可选项,表示使用投影操作符指定返回的字段,如果忽略此选项则返回所有字段。
查询 test 集合中的所有文档时,为了使显示的结果更为直观,可使用 pretty() 方法以格式化的方式来显示所有文档,方法如下:
> db.test.find().pretty()
除了 find() 方法,还可使用 findOne() 方法,它只返回一个文档。
查询条件
MongoDB 支持条件操作符,下表为 MongoDB 与 RDBMS 的条件操作符的对比,读者可以通过对比来理解 MongoDB 中条件操作符的使用方法。
操作符 | 格式 | 实例 | 与 RDBMS where 语句比较 |
---|---|---|---|
等于(=) | {<key> : {<value>}} | db.test.find( {price : 24} ) | where price = 24 |
大于(>) | {<key> : {$gt : <value>}} | db.test.find( {price : {$gt : 24}} ) | where price > 24 |
小于(<) | {<key> : {$lt : <value>}} | db.test.find( {price : {$lt : 24}} ) | where price < 24 |
大于等于(>=) | {<key> : {$gte : <value>}} | db.test.find( {price : {$gte : 24}} ) | where price >= 24 |
小于等于(<=) | {<key> : {$lte : <value>}} | db.test.find( {price : {$lte : 24}} ) | where price <= 24 |
不等于(!=) | {<key> : {$ne : <value>}} | db.test.find( {price : {$ne : 24}} ) | where price != 24 |
与(and) | {key01 : value01, key02 : value02, …} | db.test.find( {name : "《MongoDB 入门教程》", price : 24} ) | where name = "《MongoDB 入门教程》" and price = 24 |
或(or) | {$or : [{key01 : value01}, {key02 : value02}, …]} | db.test.find( {$or:[{name : "《MongoDB 入门教程》"},{price : 24}]} ) | where name = "《MongoDB 入门教程》" or price = 24 |
特定类型查询
特定类型查询结果在 test 集合中有以下文档为基础:
> db.test.find() {"_id" : Objectld("5ba7342c7f9318ea62161351"), "name" : "《MongoDB教程》", "price" : 24, "tags" : [ "MongoDB", "NoSQL", "database" ], "by": "C语言中文网"} {"_id" : Objectld("5ba747bd7f9318ea62161352"), "name" : "ava 教程", "price" : 36, "tags" : ["编程语言", "Java语言", "面向对象程序设计语言"], "by" : "C语言中文网"} {"_id" : Objectld("5ba75a057f9318ea62161356"), "name" : "王二", "age" : null }
查询 age 为 null 的字段的语法格式如下:
> db.test.find({age:null})
此语句不仅匹配出 age 为 null 的文档,其他不同类型的文档也会被查出。这是因为 null 不仅会匹配某个键值为 null 的文档,而且还会匹配不包含这个键的文档。
查询数组可使用以下语法格式:
> db.test.find( { tags:['MongoDB', 'NoSQL', 'database'] } ) {"_id" : ObjectId("5ba7342c7f9318ea62161351"), "name": "《MongoDB教程》", "price" : 24, "tags" : [ "MongoDB", "NoSQL", "database"], "by" : "C语言中文网"}
查询有 3 个元素的数组的代码如下:
> db.test.find( { tags:{$size:3} } ) {"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB","NoSQL", "database"], "by" : "C语言中文网"} {"_id" : Objectld ("5baf 9bc763ba0fk>3ccccle78"), "name" : "《Java 教程》", "price" : 36, "tags" : ["编程语言", "Java语言", "面向对象程序设计语言"], "by" : "C语言中文网"}
查询数组里的某一个值的代码如下:
> db.test.find( { tags: "MongoDB" } ) {"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB","NoSQL", "database"], "by" : "C语言中文网"}
limit() 函数与 SQL 中的作用相同,用于限制查询结果的个数,如下语句只返回 3 个匹配的结果。若匹配的结果不到 3 个,则返回匹配数量的结果:
>db.test.find().limit(3)
Skip() 函数用于略过指定个数的文档,如下语句略过第一个文档,返回后两个:
>db.test.find().skip(1)
sort() 函数用于对查询结果进行排序,1 是升序,-1 是降序,如下语句可将查询结果升序显示:
>db.test.find().sort({"price" : 1})
使用 $regex 操作符来设置匹配字符串的正则表达式,不同于全文检索,使用正则表达式无须进行任何配置。如下所示为使用正则表达式查询含有 MongoDB 的文档:
> db.test.find({tags:{$regex:"MongoDB"}}) {"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB","NoSQL", "database"], "by" : "C语言中文网"}
游标
游标是指对数据一行一行地进行操作,在 MongoDB 数据库中对游标的控制非常简单,只需使用 firid() 函数就可以返回游标。有关游标的方法参见下表。
方法名 | 作用 |
---|---|
hasNext | 判断是否有更多的文档 |
next | 用来获取下一条文档 |
toArray | 将查询结构放到数组中 |
count | 查询的结果为文档的总数量 |
limit | 限制查询结果返回数量 |
skip | 跳过指定数目的文档 |
sort | 对查询结果进行排序 |
objsLeftlnBatch | 查看当前批次剩余的未被迭代的文档数量 |
addOption | 为游标设置辅助选项,修改游标的默认行为 |
hint | 为查询强制使用指定索引 |
explain | 用于获取查询执行过程报告 |
snapshot | 对查询结果使用快照 |
使用游标时,需要注意下面 4 个问题。
1) 当调用 find() 函数时,Shell 并不立即查询数据库,而是等真正开始获取结果时才发送查询请求。
2) 游标对象的每个方法几乎都会返回游标对象本身,这样可以方便进行链式函数的调用。
3) 在 MongoDB Shell 中使用游标输出文档包含两种情况,如果不将 find() 函数返回的游标赋值给一个局部变量进行保存,在默认情况下游标会自动迭代 20 次。如果将 find() 函数返回的游标赋值给一个局部变量,则可以使用游标对象提供的函数进行手动迭代。
4) 使用清空后的游标,进行迭代输出时,显示的内容为空。
游标从创建到被销毁的整个过程存在的时间,被称为游标的生命周期,包括游标的创建、使用及销毁三个阶段。当客户端使用 find() 函数向服务器端发起一次查询请求时,会在服务器端创建一个游标,然后就可以使用游标函数来操作查询结果。
以下三种情况会让游标被销毁。
- 客户端保存的游标变量不在作用域内。
- 游标遍历完成后,或者客户端主动发送终止消息。
- 在服务器端 10 分钟内未对游标进行操作。
以下语句显示使用游标查找所有文档:
>var cursor = db.test.find() >while (cursor.hasNext()){ var doc = cursor.next(); print(doc.name); //把每一条数据都单独拿出来进行逐行的控制 print(doc); //将游标数据取出来后,其实每行数据返回的都是一个[object BSON]型的内容 printjson(doc); //将游标获取的集合以JSON的形式显示 }
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/23417.html