在关系型数据库中,可以实现基于表的各种各样的查询,以及通过投影来返回指定的列,相应的查询功能也可以在 MongoDB 中实现。同时由于 MongoDB 支持嵌套文档和数组,MongoDB 也可以实现基于嵌套文档和数组的查询。
MongoDB 查询文档使用 find() 方法。find() 方法以非结构化的方式来显示所有文档。
find() 简介
MongoDB 中查询文档使用 find() 方法。find() 方法以非结构化的方式来显示所要查询的文档, 查询数据的语法格式如下:
>db.collection.find(query, projection)
query 为可选项,设置查询操作符指定查询条件;projection 也为可选项,表示使用投影操作符指定返回的字段,如果忽略此选项则返回所有字段。
查询test集合中的所有文档时,为了使显示的结果更为直观,可使用 pretty() 方法以格式化的方式来显示所有文档,方法如下:
> db.test.find().pretty()
除了 find() 方法,还可使用 findOne() 方法,它只返回一个文档。
以下实例我们查询了集合 myColl6 中的数据:
> db.myColl6.find() { "_id" : ObjectId("5f50477ee31448829d2dfbfe"), "name" : "test1", "age" : 10 } { "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 } { "_id" : ObjectId("5f504a9fe31448829d2dfc04"), "name" : "test4", "age" : 40 } { "_id" : ObjectId("5f504a9fe31448829d2dfc05"), "name" : "test5", "age" : 50 } { "_id" : ObjectId("5f504ac8e31448829d2dfc06"), "name" : "test6", "age" : 30 } > > db.myColl6.find().pretty() // 格式化 "_id" : ObjectId("5f50477ee31448829d2dfbfe"), "name" : "test1", "age" : 10 } "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 } "_id" : ObjectId("5f504a9fe31448829d2dfc04"), "name" : "test4", "age" : 40 } "_id" : ObjectId("5f504a9fe31448829d2dfc05"), "name" : "test5", "age" : 50 } "_id" : ObjectId("5f504ac8e31448829d2dfc06"), "name" : "test6", "age" : 30 }
查询条件
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 |
特定类型查询
特定类型查询结果在 myColl3 集合中有以下文档为基础:
> db.myColl3.find() { "_id" : ObjectId("5f4f4845e8b8099c8e7dbec9"), "title" : "MongoDB教程", "info" : "MongoDB 是一个 Nosql 数据库" } { "_id" : 1, "title" : "insert指定_id", "info" : "MongoDB插入数据" } { "_id" : 2, "name" : "张三", "age" : 18, "address" : "中国" } { "_id" : ObjectId("5f4f4b95e8b8099c8e7dbeca"), "name" : "李四", "age" : 19 } { "_id" : ObjectId("5f4f4b95e8b8099c8e7dbecb"), "info" : "Hello", "car" : "buick" } { "_id" : ObjectId("5f4f510ae8b8099c8e7dbecc"), "name" : "test", "age" : null }
查询 age 为 null 的字段的语法格式如下:
> db.myColl3.find({"age":null}) { "_id" : ObjectId("5f4f4845e8b8099c8e7dbec9"), "title" : "MongoDB教程", "info" : "MongoDB 是一个 Nosql 数据库" } { "_id" : 1, "title" : "insert指定_id", "info" : "MongoDB插入数据" } { "_id" : ObjectId("5f4f4b95e8b8099c8e7dbecb"), "info" : "Hello", "car" : "buick" } { "_id" : ObjectId("5f4f510ae8b8099c8e7dbecc"), "name" : "test", "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" : "博客园"}
查询有 3 个元素的数组的代码如下:
> db.test.find( { tags:{$size:3} } ) {"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB","NoSQL", "database"], "by" : "博客园"} {"_id" : Objectld ("5baf 9bc763ba0fk>3ccccle78"), "name" : "《Java 教程》", "price" : 36, "tags" : ["编程语言", "Java语言", "面向对象程序设计语言"], "by" : "博客园"}
查询数组里的某一个值的代码如下:
> db.test.find( { tags: "MongoDB" } ) {"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB","NoSQL", "database"], "by" : "博客园"}
limit() 函数与 SQL 中的作用相同,用于限制查询结果的个数,如下语句只返回 3 个匹配的结果。若匹配的结果不到 3 个,则返回匹配数量的结果:
> db.myColl5.find() { "_id" : 1, "name" : "666", "age" : 26 } { "_id" : 2, "name" : "test1", "age" : 20 } { "_id" : 3, "name" : "test2", "age" : null } { "_id" : 4, "name" : "test3", "age" : 40 } > > db.myColl5.find().limit(2) { "_id" : 1, "name" : "666", "age" : 26 } { "_id" : 2, "name" : "test1", "age" : 20 } > > db.myColl5.find().limit(10) { "_id" : 1, "name" : "666", "age" : 26 } { "_id" : 2, "name" : "test1", "age" : 20 } { "_id" : 3, "name" : "test2", "age" : null } { "_id" : 4, "name" : "test3", "age" : 40 }
skip() 函数用于略过指定个数的文档,如下语句略过前两个文档,返回后两个:
> db.myColl5.find() { "_id" : 1, "name" : "666", "age" : 26 } { "_id" : 2, "name" : "test1", "age" : 20 } { "_id" : 3, "name" : "test2", "age" : null } { "_id" : 4, "name" : "test3", "age" : 40 } > > db.myColl5.find().skip(2) { "_id" : 3, "name" : "test2", "age" : null } { "_id" : 4, "name" : "test3", "age" : 40 }
sort() 函数用于对查询结果进行排序,1 是升序,-1 是降序,如下语句可将查询结果升序显示:
> db.myColl5.find() { "_id" : 1, "name" : "666", "age" : 26 } { "_id" : 2, "name" : "test1", "age" : 20 } { "_id" : 3, "name" : "test2", "age" : null } { "_id" : 4, "name" : "test3", "age" : 40 } > > db.myColl5.find().sort({"age":-1}) // 降序 { "_id" : 4, "name" : "test3", "age" : 40 } { "_id" : 1, "name" : "666", "age" : 26 } { "_id" : 2, "name" : "test1", "age" : 20 } { "_id" : 3, "name" : "test2", "age" : null } > > db.myColl5.find().sort({"age":1}) // 升序 { "_id" : 3, "name" : "test2", "age" : null } { "_id" : 2, "name" : "test1", "age" : 20 } { "_id" : 1, "name" : "666", "age" : 26 } { "_id" : 4, "name" : "test3", "age" : 40 }
使用 $regex 操作符来设置匹配字符串的正则表达式,不同于全文检索,使用正则表达式无须进行任何配置。如下所示为使用正则表达式查询含有 MongoDB 的文档:
> db.test.find({tags:{$regex:"MongoDB"}})
{"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB","NoSQL", "database"], "by" : "博客园"}
示例
> db.myColl6.find() { "_id" : ObjectId("5f50477ee31448829d2dfbfe"), "name" : "test1", "age" : 10 } { "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 } { "_id" : ObjectId("5f504a9fe31448829d2dfc04"), "name" : "test4", "age" : 40 } { "_id" : ObjectId("5f504a9fe31448829d2dfc05"), "name" : "test5", "age" : 50 } { "_id" : ObjectId("5f504ac8e31448829d2dfc06"), "name" : "test6", "age" : 30 } > > db.myColl6.find({"age":{$gt:40}}) // 查询age>40的文档 { "_id" : ObjectId("5f504a9fe31448829d2dfc05"), "name" : "test5", "age" : 50 } > > db.myColl6.find({"age":{$gte:40}}) // age>=40 { "_id" : ObjectId("5f504a9fe31448829d2dfc04"), "name" : "test4", "age" : 40 } { "_id" : ObjectId("5f504a9fe31448829d2dfc05"), "name" : "test5", "age" : 50 } > > db.myColl6.find({"age":{$lt:40}}) // age < 40 { "_id" : ObjectId("5f50477ee31448829d2dfbfe"), "name" : "test1", "age" : 10 } { "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 } { "_id" : ObjectId("5f504ac8e31448829d2dfc06"), "name" : "test6", "age" : 30 } > > db.myColl6.find({"age":{$lte:40}}) // age <=40 { "_id" : ObjectId("5f50477ee31448829d2dfbfe"), "name" : "test1", "age" : 10 } { "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 } { "_id" : ObjectId("5f504a9fe31448829d2dfc04"), "name" : "test4", "age" : 40 } { "_id" : ObjectId("5f504ac8e31448829d2dfc06"), "name" : "test6", "age" : 30 } > > db.myColl6.find({"age":{$ne:40}}) // age != 40 { "_id" : ObjectId("5f50477ee31448829d2dfbfe"), "name" : "test1", "age" : 10 } { "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 } { "_id" : ObjectId("5f504a9fe31448829d2dfc05"), "name" : "test5", "age" : 50 } { "_id" : ObjectId("5f504ac8e31448829d2dfc06"), "name" : "test6", "age" : 30 }
>
> db.myColl6.find({"age":30, "name":"test3"}) // age=30 and name="test3"
>
> db.myColl6.find({"age":30, "name":"test6"}) // age=30 and name="test6"
{ "_id" : ObjectId("5f504ac8e31448829d2dfc06"), "name" : "test6", "age" : 30 }
>
> db.myColl6.find({$or:[{"name":"test2"}, {"age":40}]}) // name="test2" or age=40
{ "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 }
{ "_id" : ObjectId("5f504a9fe31448829d2dfc04"), "name" : "test4", "age" : 40 }
>
> db.myColl6.find({$or:[{"name":"test2"}, {"age":{$lt:30}}]}) // name="test2" or age<30
{ "_id" : ObjectId("5f50477ee31448829d2dfbfe"), "name" : "test1", "age" : 10 }
{ "_id" : ObjectId("5f504a9fe31448829d2dfc02"), "name" : "test2", "age" : 20 }