MongoDB查询数据的多种方法(附带实例)
关系数据库中可以实现基于表的各种查询,以及通过投影操作符来返回指定的列。相应的查询功能也可以在 MongoDB 中实现。
由于支持嵌套文档和数组,MongoDB 也可以实现基于嵌套文档和数组的查询。
查询 test 集合中的所有文档时,为了使结果展示更为直观,可使用.pretty() 方法以格式化的方式进显示,具体方法如下:
除了 find() 方法,还可使用 findOne() 方法来查询文档。该方法只返回一个文档。
查询 age 为 null 的语法如下:
查询数组可使用以下语法:
查询有 3 个元素的数组的代码如下:
查询数组里的某一个文档(以tags为“MongoDB”为例)的代码如下:
limit() 方法在 MongoDB 与 SQL 中的作用是相同的,都是用于限制查询结果的个数。例如,以下代码只返回3个匹配的结果,若匹配的结果不足 3 个,则返回所有匹配的结果。
skip() 方法用于略过指定个数的文档。例如,以下代码略过 test 集合的第一个文档,返回后两个文档的查询结果:
sort() 方法用于对查询结果进行排序,值为 1 表示升序,值为 -1 表示降序。例如,以下代码将查询结果进行升序显示:
使用 $regex 操作符来设置匹配字符串的正则表达式。不同于全文检索,使用正则表达式无须进行任何配置。以下代码展示了使用正则表达式来查询含有 MongoDB 的文档:
游标的使用方法如下表所示:
在使用游标时,需要注意下面 4 个方面:
游标从创建到被销毁的整个过程所存在的时间称为游标的生命周期,具体包括游标的创建、使用及销毁这 3 个阶段。当客户端使用 find() 方法向服务器端发起一次查询请求时, MongoDB Shell 会在服务器端创建一个游标,之后便可以使用游标函数来操作查询结果。
以下 3 种情况会让游标被销毁:
以下代码展示了使用游标来查找所有文档:
由于支持嵌套文档和数组,MongoDB 也可以实现基于嵌套文档和数组的查询。
MongoDB find()方法
MongoDB 中查询文档使用 find() 方法。find() 方法以非结构化的方式来显示所要查询的文档,其语法格式如下:> db.collection.find(query, projection)其中,query 为可选项,设置查询操作符指定查询条件;projection 也为可选项,表示使用投影操作符指定返回的字段,如果忽略此选项则返回所有字段。
查询 test 集合中的所有文档时,为了使结果展示更为直观,可使用.pretty() 方法以格式化的方式进显示,具体方法如下:
> db.test.find().pretty()
除了 find() 方法,还可使用 findOne() 方法来查询文档。该方法只返回一个文档。
MongoDB查询条件
MongoDB 支持条件操作符。下表展示了 MongoDB 与 RDBMS 条件操作符的对比,读者可以通过这种对比来理解 MongoDB 条件操作符的使用方法。操作符 | MongoDB 格式 | 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 |
MongoDB特定类型查询
例如 test 集合中有以下文档数据:> db.test.find() { "_id": ObjectId("5ba7342c7f9318ea62161351"), "name": "《MongoDB教程》", "price":24, "tags": [ "MongoDB", "NoSQL", "database" ], "by": "C语言中文网" } { "_id": ObjectId("5ba747bd7f9318ea62161352"), "name": "Java教程", "price":36, "tags": [ "编程语言", "Java语言", " 面向对象程序设计语言" ], "by": "C语言中文网" } { "_id": ObjectId("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": ObjectId("5baf9b6663ba0fb3cccc1e77"), "name": "《MongoDB教程》", "price":24, "tags": ["MongoDB","NoSQL","database"], "by": "C语言中文网"}{"_id": ObjectId("5baf9bc763ba0fb3cccc1e78"), "name": "《Java教程》", "price": 36, "tags": ["编程语言","Java语言"," 面向对象程序设计语言"],"by": "C语言中文网"}
查询数组里的某一个文档(以tags为“MongoDB”为例)的代码如下:
> db.test.find( { tags:"MongoDB" } ) {"_id": ObjectId("5baf9b6663ba0fb3cccc1e77"), "name": "《MongoDB教程》", "price":24, "tags": ["MongoDB","NoSQL","database"], "by": "C语言中文网"}
limit() 方法在 MongoDB 与 SQL 中的作用是相同的,都是用于限制查询结果的个数。例如,以下代码只返回3个匹配的结果,若匹配的结果不足 3 个,则返回所有匹配的结果。
> db.test.find().limit(3)
skip() 方法用于略过指定个数的文档。例如,以下代码略过 test 集合的第一个文档,返回后两个文档的查询结果:
> db.test.find().skip(1)
sort() 方法用于对查询结果进行排序,值为 1 表示升序,值为 -1 表示降序。例如,以下代码将查询结果进行升序显示:
> db.test.find().sort({"price":1})
使用 $regex 操作符来设置匹配字符串的正则表达式。不同于全文检索,使用正则表达式无须进行任何配置。以下代码展示了使用正则表达式来查询含有 MongoDB 的文档:
> db.test.find({tags:{$regex:"MongoDB"}}) { "_id": ObjectId("5ba7342c7f9318ea62161351"), "name": "《MongoDB教程》", "price":24, "tags": [ "MongoDB", "NoSQL" ], "by": "C语言中文网" }
MongoDB游标
游标是指对数据一行一行地进行操作。在 MongoDB 数据库中,游标的控制非常简单,只需使用 find() 方法就可以返回游标。游标的使用方法如下表所示:
方法名 | 描述 |
---|---|
hasNext | 判断是否有更多的文档 |
next | 用来获取下一条文档 |
toArray | 将查询结果放到数组中 |
count | 查询的结果为文档的总数量 |
limit | 限制查询结果返回数量 |
skip | 跳过指定数目的文档 |
sort | 对查询结果进行排序 |
objsLeftInBatch | 查看当前批次剩余的未被迭代的文档数量 |
addOption | 为游标设置辅助选项,修改游标的默认行为 |
hint | 为查询强制使用指定索引 |
explain | 用于获取查询执行过程报告 |
snapshot | 对查询结果使用快照 |
在使用游标时,需要注意下面 4 个方面:
- 当调用find()方法时,MongoDB Shell并不会立即查询数据库,而是等真正开始获取结果时才发送查询请求;
- 游标对象的每个方法大部分会返回游标对象本身,这样可以方便地进行链式函数的调用;
-
在 MongoDB Shell 中,使用游标输出文档包含以下两种情况:
- 情况1:如果 find() 方法返回的游标不被赋值给一个局部变量进行保存,那么在默认情况下,游标会自动迭代 20 次;
- 情况2:如果 find() 方法返回的游标被赋值给一个局部变量,则用户可以使用游标对象提供的函数进行手动迭代。
- 当使用清空后的游标进行迭代输出时,显示的内容为空。
游标从创建到被销毁的整个过程所存在的时间称为游标的生命周期,具体包括游标的创建、使用及销毁这 3 个阶段。当客户端使用 find() 方法向服务器端发起一次查询请求时, MongoDB Shell 会在服务器端创建一个游标,之后便可以使用游标函数来操作查询结果。
以下 3 种情况会让游标被销毁:
- 客户端保存的游标变量不在作用域内;
- 游标遍历完成,或者客户端主动发送终止消息;
- 服务器端 10 min 内未对游标进行操作。
以下代码展示了使用游标来查找所有文档:
> var cursor = db.test.find() > while (cursor.hasNext()){ var doc = cursor.next(); print (doc.name); // 把每一条数据单独拿出来进行逐行的控制 print (doc) // 将游标数据取出来后,每行数据返回的都是一个[object BSON]类型的内容 printjson (doc); // 将游标获取的集合以JSON格式显示 }