一、引言
上一篇文章我们已经介绍了MongoDB数据库的最基本操作,包括数据库的创建、使用和删除数据库,文档的操作也涉及到了文档的创建、删除、更新和查询,当然也包括集合的创建、重命名和删除。有了这些基本操作,大家第一次使用MongoDb数据库的时候就不会慌张,慢慢操作就可以了。虽然上一篇文章简单介绍了一些文档的查询,那都是最基本的,由于文档的查询涉及的内容比较多,所以我们需要单独写一篇文章来专门介绍有关文档的查询的详细信息。废话不多说,马上开始我们今天的写作吧。
二、MongDB查询的详解
我比较直接,直接上内容,有关查询的每个方法都有示例代码,应该不是很难。
1、find()查询方法:根据查询条件返回符合条件的所有文档
MongoDB 查询文档使用 find() 方法,find() 方法以非结构化的方式来显示所有文档。
语法:db.collectionName.find(query, projection)
参数说明:
query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。格式类似{<key>:1,<key>:1,_id:0},0值表示不显示,其他值均为显示,无论正负值。该参数控制不显示的字段,需要显示的不在该参数里书写就可以。
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
>db.collectionName.find().pretty()
pretty() 方法以格式化的方式来显示所有文档。
1.1、示例代码:查询所有文档
//find()方法内没有任何查询条件,查询所有记录,find({})方法表示空条件,也就是无条件,和find()方法查询结果一样。 > db.students.find() { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } > db.students.find({}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" }
1.2、示例代码:根据指定条件查询文档
//查询【name】字段的值是【angShiYu】 的文档 > db.students.find({name:"FangShiYu"}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } //查询【sex】性别字段是【1】男的所有文档 > db.students.find({sex:1}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } //查询【sex】性别字段是【1】男的,并且【age】字段的值是【22】的所有文档 > db.students.find({sex:1,age:22}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } >
1.3、示例代码:控制字段的显示
//find({查询条件},{控制字段显示与否})方法的第二个参数控制查询出来的字段的显示,_id:0,表示不显示,其他值均为显示,不写该字段也会显示,_id主键除外的字段,需要显示就写上,但是其值不能是0,比如:address:0,这会产生错误,address:1/-1都会显示 //查询【sex】性别字段是【1】男的所有文档,_id字段不显示,只显示【name】,【age】,【school】字段 > db.students.find({sex:1},{_id:0,name:-1,age:1,school:1}) { "name" : "FangShiYu", "age" : 22, "school" : "ZheJiangDaXue" } { "name" : "HuangFeiHong", "age" : 32, "school" : "GuangDongDaXue" } >
1.4、示例代码:格式化文档
//使用pretty()格式化输出 > db.students.find({sex:0}).pretty() { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" }
2、findOne()查询方法:查询结果只会返回符合条件的第一条文档
MongoDB 查询文档使用 findOne()方法查询符合条件的第一条文档,使用和find()方法类似,并以非结构化的方式来显示所有文档。
语法:db.collectionName.findOne(query, projection)
参数说明:
query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。格式类似{<key>:1,<key>:1,_id:0},非0的值表示显示,0表示不显示
findOne()方法不支持pretty()方法。
2.1、示例代码:显示符合条件的第一条记录
//性别【sex】是【1】男性的有两条文档,但是只显示了第一条 > db.students.findOne({sex:1}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" }
2.2、示例代码:控制字段列的显示
> db.students.findOne({sex:1},{_id:0,name:1,age:1,sex:1,school:1,address:1}) { "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } >
2.3、示例代码:findOne()方法不支持pretty()方法
> db.students.find({sex:1},{_id:0,name:-1,age:1,school:1}).pretty() 2018-03-29T13:27:12.277+0800 E QUERY [thread1] TypeError: db.students.findOne(...).pretty is not a function : @(shell):1:1
3、条件操作符
如果你熟悉常规的 SQL 数据,通过下表可以更好的理解 MongoDB 的条件语句查询:
3.1、: 等于 :查询指定字段的值等于某个具体的值的时候返回符合条件的文档
语法:db.collectionName.find({<key>:<value>})
参数说明:
key:需要执行查询判断的字段名
value:这个值是一个具体的数值,并且这个值需要和Key字段里面的值进行比较,只有当Key字段的值等于Value的时候,才返回符合条件的文档
实例代码:
> db.students.find({"name":"FangShiYu"}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" }
3.2、$lt 小于:查询指定字段的值小于某个具体的值的时候返回符合条件的文档
语法:db.collectionName.find({<key>:{$lt:<value>}})
参数说明:
key:需要执行查询判断的字段名
value:这个值是一个具体的数值,并且这个值需要和Key字段里面的值进行比较,只有当Key字段的值小于Value的时候,才返回符合条件的文档
实例代码:
>db.students.find({"age":{$lt:27}}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" }
3.3、$lte 小于或等于 :查询指定字段的值在小于或者等于某个具体的数值时返回所有符合条件的文档
语法:db.collectionName.find({<key>:{$lte:<value>}})
参数说明:
key:需要执行查询判断的字段名
value:这个值是一个具体的数值,并且这个值需要和Key字段里面的值进行比较,只有当Key字段的值小于或者等于Value的时候,才返回符合条件的文档
实例代码:
> db.students.find({"age":{$lte:27}}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } >
3.4、$gt 大于:查询指定字段的值是大于某个具体的值的所有文档
语法:db.collectionName.find({<key>:{$gt:<value>}})
参数说明:
key:需要执行查询判断的字段名
value:这个值是一个具体的数值,并且这个值需要和Key字段里面的值进行比较,只有当Key字段的值大于Value的时候,才返回符合条件的文档
实例代码:
> db.students.find({"age":{$gt:27}}) { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } >
3.5、$gte 大于或等于 :查询指定字段的值是大于或者等于某个值的所有文档
语法:db.collectionName.find({<key>:{$gte:<value>}})
参数说明:
key:需要执行查询判断的字段名
value:这个值是一个具体的数值,并且这个值需要和Key字段里面的值进行比较,只有当Key字段的值比Value大或者相等,并返回符合条件的文档
实例代码:
> db.students.find({"age":{$gte:24}}) { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } >
3.6、$ne 不等于:查询指定字段的值不等于某个特定值并返回符合条件的文档
语法:db.collectionName.find({<key>:{$ne:<value>}})
参数说明:
key:需要执行查询的字段名
value:这个值是一个具体的数值,并且这个值需要和Key字段里面的值进行比较,不相等,就执行查询,并返回符合条件的记录
实例代码:
> db.students.find({"sex":{$ne:1}}) { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" }
3.7、$gte 和 $lte 大于等于、小于等于:查询指定字段的值属于某个指定值的范围的所有文档,满足条件返回文档
语法:db.collectionName.find({<key>:{$gte:<value1>,$lte:<value2>}})
参数说明:
key:进行比较的字段名
$gte:大于等于
value1:这个值是要大于等于的那个值
$lte:小于等于
value2:这个值是要小于等于的那个值
value1和value2形成一个比较的范围,可以针对名称为Key的字段的值进行判断
实例代码:
> db.students.find({"age":{$gte:20,$lte:27}}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } >
4、And和Or 的使用
4.1、and 的使用:和的关系,必须满足所有的条件才能完成查询
语法:db.collectionName.find({query1,query2,query3,...queryn})
参数说明:
query1-n:查询条件,这些查询条件必须在一个花括号({})里面,这种使用方式才是and的关系
示例代码:
>db.students.find({age:{$gt:24},sex:0}) { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } >
4.2、or 的使用:或的关系,满足条件之一就可以完成查询
语法:db.collectionName.find({$or:[{query1},{query2},{query3},...{queryn}]})
参数说明:
query1-n:是查询条件,条件之间是或(or)的关系,并且“[]”方括号不能省略
示例代码:
>db.students.find({$or:[{sex:0},{age:22}]}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } >
4.3、and 和 or
语法:db.collectionName.find({query1,query2,query3,...,$or:[{query4},{query5},{query6},...]]})
参数说明:
query1-n:都是查询的条件,前面的查询条件和后面的查询条件是or的关系,“$or”前面部分的查询条件是and的关系,后面的是or的关系
示例代码:
> db.students.find({age:{$gt:24},sex:0,$or:[{sex:1},{age:27}]}) { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } >
5、以ID作为查询条件
语法:db.collectionName.find({_id:ObjectId("id的值")})
参数说明:
_id:Mongodb自动生成的主键,这个是固定写法,不能改变。
ObjectId:代表是主键_id的值,整个的写法是:ObjectId("5ab9de223afa6504457050e2"),这个方法的值才是_id主键的值,其他写法是错误
代码实例:
> db.students.find({_id:ObjectId("5ab9de223afa6504457050e2")}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } >
6、count()方法:统计查询文档记录的条数
语法:db.collectionName.find({query1,query2...queryn}).count()
参数说明:
query1-n:查询条件,可以有多个查询条件,多个查询条件之间是and的关系。
代码实例:
> db.students.find({"sex":1}).count() 2 >
7、查询以什么值开头
语法:db.collectionName.find({<key>:/^value/})
参数说明:
key:要查询的字段的名称
value:检查key字段的值中是否以value开始,格式:/^value/,斜杠“/”和“^”不能省略
代码实例:
> db.students.find({name:/^F/}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" }
8、查询某个字段总是否包含另一个值
语法:db.collectionName.find({<key>:/value/})
参数说明:
key:查询的字段的名称
value:查询key字段的值中是否包含着value的值,前后的两个斜杠“/”不能省略
代码实例:
> db.students.find({name:/ng/}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" }
9、limit()和skip()方法的使用
9.1、limit()方法:只显示num条
语法:db.collectionName.find({query}).limit(num)
参数说明:
query:查询条件
num:条数,仅仅显示的条数
示例代码:
//显示前2条 >db.students.find().limit(2) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" }
9.2、skip()方法:跳过num条后继续显示
语法:db.collectionName.find({query}).skip(num)
参数说明:
query:查询条件
num:跳过的条数
示例代码:
//跳过2条,从第3条开始显示 >db.students.find().skip(2) { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } >
9.3、skip()和 limit() 联合使用:分页显示
语法:db.collectionName.find({query}).skip(pageIndex*pageSize).limit(pageSize)
参数说明:
query:查询条件
pageIndex:页码索引,从0开始
pageSize:每页显示的条数
示例代码:
//跳过1条,从第2条开始显示2条 > db.students.find().skip(1).limit(2) { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } >
10、sort()方法:针对某个字段进行升序或者降序排序
语法:db.collectionName.find({query}).sort({<key>:1升序|-1 降序})
参数说明:
query:查询条件
key:针对排序的字段名,1为升序,-1为降序,不能为其他值
示例代码:
//按年龄(age)升序排列 > db.students.find().sort({age:1}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } //按年龄(age)降序排列 > db.students.find().sort({age:-1}) { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" }
11、$type 操作符:可以针对某个字段查询该字段的值和具体数据类型相匹配的文档
语法:db.collectionName.find({<key>:{$type:<value>}})
参数说明:
key:要操作的字段名称
value:表示类型对应的值
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
MongoDB 中可以使用的类型如下表所示:
类型 数字 备注
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 已废弃。
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with -1.
Max key 127
示例代码:
//如果想获取 "school" 集合中 name 为 String 的数据,你可以使用以下命令: > db.students.find({"name":{$type:2}}) { "_id" : ObjectId("5ab9de223afa6504457050e2"), "name" : "FangShiYu", "age" : 22, "sex" : 1, "school" : "ZheJiangDaXue", "address" : "GuangDongGuangZhou" } { "_id" : ObjectId("5ab9de223afa6504457050e3"), "name" : "YanYongChun", "age" : 27, "sex" : 0, "school" : "FuJianDaXue", "address" : "FuJianNanTianRen" } { "_id" : ObjectId("5ab9de3c3afa6504457050e4"), "name" : "HuangFeiHong", "age" : 32, "sex" : 1, "school" : "GuangDongDaXue", "address" : "GuangDongFoShan" } >
三、总结
今天就写到这里了,有关查询和更新的内容还很多,今天只是介绍一个大概的内容,让大家对MongoDB的操作有一个初步的印象。我们以后会用更多的章节介绍查询和跟新的内容,包括条件操作符,修改操作符,还有一些特殊的操作符,正因为这部分的内容很多,所以需要我们使用单独的章节来介绍其内容。不忘初衷,继续努力吧。