DBA MongoDB 文档查询

数据准备

在学习文档查询之前,先录入以下数据:

> db.collection.drop()
> db.collection.insertMany(
	[
		{
			_id:1,
			name:"Jack",
			gender:"male",
			age:18,
			grades:
            {
                Js:88,
                Py:92,
                Go:78
            },
			class:{
            	name:"三年级一班",
				numPeople:30,
			}
		},
		{
			_id:2,
			name:"Tom",
			gender:"male",
			age:19,
			grades:{
				Js:72,
				Py:81,
				Go:56,
			},
			class:{
				name:"三年级一班",
				numPeople:30,
			}
		},
		{
			_id:3,
			name:"Ken",
			gender:"male",
			age:20,
			grades:{
				Js:61,
				Py:72,
				Go:96,
			},
			class:{
				name:"三年级一班",
				numPeople:30,
			}
		},
		{
			_id:4,
			name:"Keisha",
			gender:"female",
			age:17,
			grades:{
				Js:31,
				Py:42,
				Go:26,
			},
			class:{
				name:"三年级二班",
				numPeople:21,
			}
		},
		{
			_id:5,
			name:"Kelly",
			gender:"female",
			age:18,
			grades:{
				Js:71,
				Py:64,
				Go:19,
			},
			class:{
				name:"三年级二班",
				numPeople:21,
			}
		}
	]
)

基础查询

查询与格式化

​ 下面是对集合查询文档的基础命令:

命令 描述
db.集合名.find(query) 查询符合条件的所有文档,如不指定查询条件则返回全部文档
db.集合名.findOne(query) 查询符合条件的所有文档,如不指定查询条件则返回一条文档
pretty() 对查询结果进行标准的JSON格式化显示

​ 使用find()方法可以查出一个集合下所有的文档,或者指定条件查询特定的文档:

> db.collection.find()
> db.collection.find({"name" : "Jack"})

​ 使用.pretty()方法可以对查询结果进行标准的JSON格式化:

> db.collection.find().pretty()

指定查询键

​ 如果想查询指定的键,只获取某一字段与值,则可以对find()函数的第二参数进行填写,第二参数默认为{}。

​ 示例如下:

> db.collection.find({"name" : "Jack"}, {"grades" : 1})
{ "_id" : 1, "grades" : { "Js" : 88, "Py" : 92, "Go" : 78 } }

​ 如果想隐藏掉_id字段,则可以通过第二参数中_id对应0来隐藏:

> db.collection.find({"name" : "Jack"}, {"grades" : 1, "_id" : 0})
{ "grades" : { "Js" : 88, "Py" : 92, "Go" : 78 } }

大小与个数

​ 下面是查询集合中文档个数与集合大小的命令:

命令 描述
db.集合名.count() 返回集合中文档个数
db.集合名.totalSize() 统计集合下所有文档的大小,规则为集合索引信息+数据压缩存储后的大小

​ 示例演示如下:

> db.collection.count()
5
> db.collection.totalSize()
40960

查询子文档

​ 层级关系可以用.点符号来进行查询,如下示例,我想查询Jack同学的Js成绩:

> db.collection.find({"name" : "Jack"}, {"grades.Js" : 1, "_id" : 0})
{ "grades" : { "Js" : 88 } }

显示结果

​ limit()方法可跟在查询之后,用于显示指定的条目:

> db.collection.find().pretty().limit(2)

​ skip()方法可跟在limit()方法之后,用于指定显示第几条数据,从0开始即使:

> db.collection.find().pretty().limit(2).skip(1)  # 显示第二条数据

​ sort()方法可跟在查询或者显示结果的方法之后,指定特定字段对显示结果进行排序,1为升序,-1为降序:

> db.collection.find({},{"age" : 1, "_id" : 0}).sort({"age" : 1})

修改器查询

等值查询

MongoDB中在find()或者findOne()里可指定的等值查询语法如下:

条件语法 描述
等值查询
{ k : { $eq : v } } 同上,等值查询

​ 示例,查询年龄是18的文档,拿名字以及年龄:

> db.collection.find({"age" : 18}, {"_id" : 0, "name": 1, "age" : 1})
{ "name" : "Jack", "age" : 18 }
{ "name" : "Kelly", "age" : 18 }
> db.collection.find({"age" : {$eq : 18}}, {"_id" : 0, "name": 1, "age" : 1})
{ "name" : "Jack", "age" : 18 }
{ "name" : "Kelly", "age" : 18 }

比较查询

MongoDB中在find()或者findOne()里可指定的比较查询语法如下:

条件语法 描述
{ k : { $lt : v } } 小于查询
{ k : { $lte : v } } 小于或等于
{ k : { $gt : v } } 大于查询
{ k : { $gte : v } } 大于或等于
{ k : { $ne : v } } 不等于

​ 示例,查询年龄大于19岁的文档,拿名字以及年龄:

> db.collection.find({"age" : {$gt : 19}}, {"_id" : 0, "name": 1, "age" : 1})
{ "name" : "Ken", "age" : 20 }

​ 示例,查询Js成绩小于80的文档,拿名字以及Js成绩:

> db.collection.find({"grades.Js" : {$lt : 80}}, {"_id" : 0, "name": 1, "grades.Js" : 1})
{ "name" : "Tom", "grades" : { "Js" : 72 } }
{ "name" : "Ken", "grades" : { "Js" : 61 } }
{ "name" : "Keisha", "grades" : { "Js" : 31 } }
{ "name" : "Kelly", "grades" : { "Js" : 71 } }

包含查询

​ MongoDB中在find()或者findOne()里可指定的包含查询语法如下:

条件语法 描述
{ k : { $in : [ v1, v2, … ] } } 包含查询,如果数组中v只有1个,则为等值查询
{ k : { $nin : [ v1, v2, … ] } } 不包含查询

​ 示例,查询年龄在18,19,20岁的文档,拿名字以及年龄:

> db.collection.find({"age" : {$in : [18, 19, 20]}}, {"_id" : 0, "name": 1, "age" : 1})
{ "name" : "Jack", "age" : 18 }
{ "name" : "Tom", "age" : 19 }
{ "name" : "Ken", "age" : 20 }
{ "name" : "Kelly", "age" : 18 }

逻辑查询

​ MongoDB中在find()或者findOne()里可指定的逻辑查询语法如下:

条件语法 描述
AND条件
同上,AND条件
OR条件
{ k : { $not : {条件 : v } } } NOT条件,仅支持对单个k的条件
NOT条件,可支持对多个k的条件

​ 示例$and,查询Js成绩大于80,并且年龄小于22的文档,拿名字以及Js成绩:

> db.collection.find({"grades.Js" : {$gt : 80}, "age" : {$lt : 22}}, {"_id" : 0, "name" : 1, "grades.Js" : 1})
{ "name" : "Jack", "grades" : { "Js" : 88 } }

> db.collection.find(
	{
		$and:[
			{"grades.Js" : {$gt : 80}},
			{"age" : {$lt : 22}}
		]
	},
	{
		"_id" : 0,
		"name" : 1,
		"grades.Js" : 1
	}
  )
{ "name" : "Jack", "grades" : { "Js" : 88 } } 

​ 示例$or,查询年龄是17岁或者Js成绩大于80的文档,拿名字,年龄以及Js成绩:

> db.collection.find(
	{
		$or:[
			{"grades.Js" : {$gt : 80}},
			{"age" : {$eq : 17}}
		]
	},
    {
		"_id" : 0,
		"name" : 1,
        "age" : 1,
		"grades.Js" : 1
	}
)
{ "name" : "Jack", "age" : 18, "grades" : { "Js" : 88 } }
{ "name" : "Keisha", "age" : 17, "grades" : { "Js" : 31 } }

​ 示例$not,查询性别不是male的文档,拿名字和性别:

> db.collection.find(
	{
    	"gender" : {$not : {$eq : "male"}}
    },
    {
    	"_id" : 0,
    	"name" : 1,
    	"gender" : 1,
    }
)
{ "name" : "Keisha", "gender" : "female" }
{ "name" : "Kelly", "gender" : "female" }

​ 示例$nor,查询性别不是male,名字不是kelly的文档:

> db.collection.find(
	{
		$nor : [
			{"gender" : "male"},
			{"name" : "Kelly"}
		]
	},
	{
		"_id" : 0,
		"name" : 1,
        "age" : 1,
	}
)
{ "name" : "Keisha", "age" : 17 }

存在与类型

​ MongoDB中在find()或者findOne()里可指定的存在与类型查询语法如下:

语法格式 描述
查询v为null的k,或者没有这个k的文档
{ k : { $exists : bool }} 查询存在或不存在该k的文档
{ k : { $type: “type” }} 查询该k的v为指定类型的文档

​ 示例,null,查询不存在school键的文档,仅展示一个:

> db.collection.findOne({"school" : null})
> db.collection.findOne({"school" : {$exists : false}})

​ 示例,查询name为string类型的文档,仅展示一个:

> db.collection.findOne({"name" : {$type : "string"}})

​ 在查询类型时,你也可以使用数字编号进行代替:

> db.collection.findOne({"name" : {$type : 2}})

​ $type的数字编号如下表所示:

类型 数字 备注
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

取余与正则

​ MongoDB中在find()或者findOne()里可指定的取余与正则查询语法如下:

语法格式 描述
{ k : { $mod : [ 除数, 余数 ] } } 查询k的v是取余结果值的文档
{ k :{ $regex : /表达式/ } } 查询k的v是被正则表达式所匹配的文档

示例,查询age的值是除2余0的文档:

> db.c1.find({"age":{$mod:[2,0]}});  # 18,20年龄的都会查出来

​ 示例,查询key的值被正则表达式所匹配的文档:

 > db.c1.find({"name":{$regex:/^J.{2}k$/}});

数组的条件

​ MongoDB中在find()或者findOne()里可指定的数组的条件查询语法与获取语法如下:

语法格式 描述
{ k : { $all : [ v1, v2, … ] } } 匹配所有k为数组类型,且k的元素均在查询条件中的文档
{ k : { $elemMatch : { k : v } } 匹配所有k为数组类型,且k的元素均在查询条件范围中的文档,需要配合其他修改器
{ k : { $size : int } } 匹配所有k为数组类型,且k的长度与查询条件设定长度一致的文档
{ k : { $slice : [ start, stop ] || int } } 匹配所有k为数组类型的文档,返回数组中的元素,可进行切片或取一个的操作,位置在指定第二参数(元素获取语法)

​ 先创建一个集合:

> db.array.drop()
> db.array.insertMany([{"k" : [1, 2, 3, 4, 5]}, {"k" : [1, 2, 3, 4, 5, 6]}])

​ 示例,$all,匹配规则,必须包含1,2,3,4,5,多一个不行,少一个也不行:

> db.array.find({"k" : {$all : [1, 2, 3, 4, 5]}})

​ 示例,$elemMatch,匹配规则,包含1,2,3即可:

> db.array.find({"k" : {$elemMatch : {$in:[1, 2, 3]}}})

​ 示例,$size,返回长度为5的数组:

> db.array.find({"k" : {$size : 5}})

​ 示例,$slice,从第一个开始,向后取3个:

> db.array.find({"k" : {$type : "array"}}, {"k" : {$slice : [1, 3]}})
{ "_id" : ObjectId("6048e85d6be9382bc8346b60"), "k" : [ 2, 3, 4 ] }
{ "_id" : ObjectId("6048e85d6be9382bc8346b61"), "k" : [ 2, 3, 4 ] }

$where查询

​ 最强大的一种查询,能够查询到任意的你想查询的信息,但是查询时不会走索引,所以尽量少用。

​ 它其实是书写一个JavaScript函数进行查询,如下所示,查询所有成绩大于200分的文档:

db.collection.find({
	$where: function (){
		if (this.grades.Js + this.grades.Go + this.grades.Py > 200){
			return true
		}
		return false
	}
})

# return false,不返回文档
# return true,返回文档
# 每次的this都是新的文档

​ $where本身会将BSON文档转换为JavaScript可识别的对象,所以查询时会非常慢。

posted @ 2021-03-12 23:13  云崖君  阅读(66)  评论(0编辑  收藏  举报