《快速掌握 MongoDB 数据库(二)》笔记-阿里云大学

4、数据操作(重点)

只要是数据库那么就绝对离不开最为核心的功能:CRUD,所以在MongoDB里面对数据的操作也是有支持的,需要提醒的是,除了增加之外,其它的都很麻烦。

4.1、数据增加

使用以下指令可以实现数据的增加操作。

db.集合.insert()

范例:增加一个简单数据

db.infos.insert({"url":"www.mldn.cn"});

范例:保存数组

db.infos.insert([
    {"url":"www.mldn.cn"} ,
    {"url":"www.mldnjava.cn"}]);

如果要想保存多个数据,那么就使用数组。

范例:保存10000个数据?(用javascript)

for (var x=0;x<10000;x++){
    db.infos.insert({"url":"mldn - " + x});
}

如果数据保存很多的情况下,列表时不会全部列出,它只会列出部分的内容。这是MongoDB区别于MYSQL的一个蛮好的特性。

4.2、数据查询

任何的数据库之中,数据的查询操作都是最为麻烦的,而在MongoDB数据库里面,对于查询的支持非常到位,包括有关系运算、逻辑运算、数组运算、正则运算等等。

首先对于数据的查询操作核心的语法:

db.集合名称.find({查询条件}[,{设置显示的字段}])

范例:最简单的用法就是直接使用find()函数完成查询

db.infos.find();

范例:希望查询出url为"www.mldn.cn"的数据

db.infos.find({"url":"www.mldn.cn"});

发现在进行数据查询的时候也是按照JSON的形式设置的相等关系。它在整个开发之中都不可能离开JSON数据。

对于设置的显示字段严格来讲就称为数据的投影操作 。如果不需要显示的字段设置“0”,而需要显示的字段设置“1”

范例:不想显示“_id”

db.infos.find({"url":"www.mldn.cn"},{"_id":0});
db.infos.find({"url":"www.mldn.cn"},{"_id":0,"url":1});

大部分的情况下,这种投影操作的意义不大。同时对于数据的查询也可以使用pretty()函数进行漂亮显示。

范例:漂亮显示

db.infos.find({"url":"www.mldn.cn"},{"_id":0,"url":1}).pretty();

数据列多的时候一定可以看出华丽的显示效果。

范例:查询单个数据

db.infos.findOne({"url":"www.mldn.cn"},{"_id":0,"url":1});

利用以上的查询可以实现格式化的输出效果,前提:列的内容必须多。

此处阿里云的教学视频有个坑:中间缺内容(视频3.4.2.1-3.4.2.7的内容缺失,找到魔乐科技-合作方官网继续学习和记录,https://www.mldn.cn/my/course/45)

4.2.1、关系运算

在MongoDB里面支持关系查询操作:大于($gt)、小于($lt)、大于等于($gte)、小于等于($lte)、不等于($ne)、等于(key:value)。但是要想让这些操作可以正常使用,那么需要准备出一个数据集合。

范例:定义一个学生信息集合

db.student.drop();
db.student.insert({"name":"张三","sex":"男","age":19,"score":89,"address":"海淀区"});
db.student.insert({"name":"李四","sex":"女","age":20,"score":59,"address":"朝阳区"});
db.student.insert({"name":"王五","sex":"女","age":19,"score":99,"address":"西城区"});
db.student.insert({"name":"赵六","sex":"男","age":20,"score":100,"address":"东城区"});
db.student.insert({"name":"孙七","sex":"男","age":19,"score":20,"address":"海淀区"});
db.student.insert({"name":"王八","sex":"女","age":21,"score":0,"address":"海淀区"});
db.student.insert({"name":"刘九","sex":"男","age":19,"score":70,"address":"朝阳区"});
db.student.insert({"name":"钱十","sex":"女","age":21,"score":56,"address":"西城区"});

插入后可以用db.student.find().pretty();看看美化的效果是啥意思。

范例:查询姓名是张三的学生信息

db.student.find({"name":"张三"}).pretty();

范例:查询性别是男的学生信息

db.student.find({"sex":"男"}).pretty();

范例:查询年龄大于19岁的学生

db.student.find({"age":{"$gt":19}}).pretty();

范例:成绩大约等于60分的学生

db.student.find({"score":{"$gte":60}}).pretty();

范例:查询姓名不是王五的信息

db.student.find({"name":{"$ne":"王五"}}).pretty();

此时与之前最大的区别就在于,在一个JSON结构里面需要定义其它的JSON结构,并且这种风格在日后通过程序进行操作的时候依然如此。

4.2.2、逻辑运算

逻辑运算主要就是三中类型:与($and)、或($or)、非($not、$nor)

范例:查询年龄在19~20岁的学生信息

db.student.find({"age":{"$gte":19,"$lte":20}}).pretty();

在进行逻辑运算的时候“and”的连接是最容易的,因为只需要利用“,”分割若干个条件即可。

范例:查询年龄大于19岁,或者成绩大于90分的学生信息

db.student.find({"$or": [
	{"age":{"$gt":19}},
	{"score":{"$gt":90}}
]}).pretty();

范例:也可以进行或的求反操作

db.student.find({"$nor": [
	{"age":{"$gt":19}},
	{"score":{"$gt":90}}
]}).pretty();

针对于或的操作可以试下一个求反的功能。

在这几个逻辑运算之中,与的连接最简单的,而或的连接需要为数据设置数组的过滤条件。

4.2.3、求模

模的运算使用“$mod”来完成,语法"{mod:[数字,余数]}"。

范例:求模

db.student.find({"age" : {"$mod" : [20,1]}}).pretty();

其实实现的就是age对20取余,如果取余结果等于1则匹配。

利用求模计算可以编写一些数学的计算公式。

4.2.4、范围查询

只要是数据库,必须存在有"$in"(在范围之中)、"$nin"(不在范围之中)
范例:查询姓名是“张三”、“李四”、“王五”的信息

db.student.find({"name" : {"$in" : ["张三","李四","王五"]}}).pretty();

范例:查询姓名不是“张三”、“李四”、“王五”的信息

db.student.find({"name" : {"$nin" : ["张三","李四","王五"]}}).pretty();

在实际的工作之中,范围的操作很重要。

4.2.5、数组查询

首先在mongoDB里面是支持数组保存的,一旦支持了数据保存,就需要针对于数组的数据进行匹配。

范例:保存一部分的数组内容

db.student.insert({"name":"谷大神-A","sex":"男","age":19,"score":89,"address":"海淀区","course": ["语文","数学","英语","音乐","政治"]});
db.student.insert({"name":"谷大神-B","sex":"男","age":19,"score":89,"address":"海淀区","course": ["语文","数学"]});
db.student.insert({"name":"谷大神-C","sex":"男","age":19,"score":89,"address":"海淀区","course": ["语文","数学","英语"]});
db.student.insert({"name":"谷大神-D","sex":"男","age":19,"score":89,"address":"海淀区","course": ["英语","音乐","政治"]});
db.student.insert({"name":"谷大神-E","sex":"男","age":19,"score":89,"address":"海淀区","course": ["语文","政治"]});

此时的数据包含有数组内容,而后需要针对于数组数据进行判断,可以使用几个运算符:$all、$size、$slice、$elemMatch

范例:查询同时参加语文和数学课程的学生:现在两个数组内容都需要保存,所以使用{"$all":[内容1,内容2,...]}

db.student.find({"course":{"$all":["语文","数学"]}}).pretty();

现在所有显示的学生信息里面包含语文和数学的内容,儿如果差一个内容的不会显示。

虽然"$all"计算可以用于数组上,但是也可以用于一个数据的匹配上。

范例:查询学生地址是“海淀区”的信息

db.student.find({"address":{"$all":["海淀区"]}}).pretty();

既然在集合里面现在保存的是数组信息,那么数组就可以利用索引操作,使用"key.index"的方式来定义索引

范例:查询数组中第二个内容(index=1,索引下标从0开始)为“数学”的信息

db.student.find({"course.1":"数学"}).pretty();

使用"$size"来作为数量的控制。

范例:要求查询出只参加两门课程的学生

db.student.find({"course":{"$size":2}}).pretty();

发现在进行数据查询的时候,只要是内容符合条件,数组的内容就全部显示出来了,但是现在希望可以控制数组返回的数量,那么可以使用"$slice"进行控制。

范例:返回年龄为19岁所有学生的信息,但是要求只显示两门参加课程。

db.student.find({"age":19},{"course":{"$slice":2}}).pretty();

现在只取得了前两门的信息,那么也可以设置负数表示后两门的信息。

db.student.find({"age":19},{"course":{"$slice":-2}}).pretty();

或者只是取出中间部分的信息。

db.student.find({"age":19},{"course":{"$slice":[1,2]}}).pretty();

在此时设置的两个数据里面第一个数据表示要跳过的数据量,而第二个数据表示返回的数量。

4.2.6、嵌套集合运算

在MongoDB数据里面每一个集合数据可以继续保存其它的集合数据,例如:有些学生需要保存家长信息。

范例:增加数据

db.student.insert({"name":"高大拿-A","sex":"男","age":19,"score":89,"address":"海淀区","course": ["语文","数学","英语","音乐","政治"], 
	"parents":[
	{"name":"高大拿-A(父亲)","age":50,"job":"工人"},
	{"name":"高大拿-A(母亲)","age":46,"job":"职员"}]});
db.student.insert({"name":"高大拿-B","sex":"男","age":19,"score":89,"address":"海淀区","course": ["语文","数学"], 
	"parents":[
	{"name":"高大拿-B(父亲)","age":50,"job":"处长"},
	{"name":"高大拿-B(母亲)","age":46,"job":"局长"}]});
db.student.insert({"name":"高大拿-C","sex":"男","age":19,"score":89,"address":"海淀区","course": ["语文","数学","英语"], 
	"parents":[
	{"name":"高大拿-C(父亲)","age":50,"job":"工人"},
	{"name":"高大拿-C(母亲)","age":46,"job":"局长"}]});

此时给出的内容是嵌套的集合,而这种集合的数据的判断只能够通过"$elemMatch"完成。

范例:查询出父母有人是局长的信息

db.student.find({"$and":[
	{"age":{"$gte":19}},
	{"parents": {"$elemMatch":{"job":"局长"}}}
]}).pretty();

由于这种查询的时候条件比较麻烦,所以如果可能,尽量别搞这么复杂的数据结构。

4.2.7、判断某个字段是否存在

使用"$exists"可以判断某个字段是否存在,如果设置为true表示存在,如果设置为false就表示不存在。

范例:查询具有parents成员的数据。

db.student.find({"parents":{"$exists":true}}).pretty();

范例:查询不具有course成员的数据。

db.student.find({"course":{"$exists":false}}).pretty();

可以利用此类查询来进行一些不需要的数据的过滤。

4.2.8、条件查询

实际上习惯于传统关系型数据库开发的我们对于数据的筛选,可能首先想到的是WHERE子句,所以在MongoDB里面也提供有“$where”。

范例:使用where进行数据查询,查询年龄大于20的

db.student.find({"$where":"this.age>20"}).pretty();

注意,"$where"这种,语法上不加引号也没错,但是建议加上。this表示每一条都进行循环判断,判断时是当前对象。针对$where的写法可以简化。

db.student.find("this.age>20").pretty();

对于“$where”是可以简化的,但是这类的操作是属于进行每一行的信息判断,对于数据量较大的情况不方便使用。实际上以上的代码严格来讲属于编写一个操作的函数。如下:

db.student.find(function(){
    return this.age > 20;
}).pretty();

代码没写function就相当于自带了一个function()。写完整了加上“$where”如下:

db.student.find({"$where":function(){
    return this.age > 20;
}}).pretty();

以上只是查询了一个判断,如果要想实现多个条件的判断,那么就需要使用and连接。

db.student.find({"$and":[
    {"$where":"this.age>19"},{"$where":"this.age<21"}
]}).pretty()

虽然这种形式的操作可以实现数据查询,但是最大的缺点是将在MongoDB里面保存的BSON

数据变为了Javascript的语法结构,这样的方式不方便使用数据库的索引机制。

4.2.9、正则运算

如果要想实现模糊查询,那么必须使用正则表达式,而且正则表达式使用的是语言Perl兼容的正则表达式形式。如果要想实现正则使用,则按照如下的定义格式:

基础语法:{key: 正则标记};

完整语法:{key: {"$regex" : 正则标记, "$options": 选项}}

|-  对于options主要是设置正则的信息查询的标记:

          |-   "i" : 忽略字母大小写

          |-   "m" : 多行查找

          |-   "x" : 空白字符除了被转义的或在字符位中以外的完全被忽略

          |-   "s" : 匹配所有的字符(圆点、“.”),包括换行的内容

|-  需要注意的是,如果是直接使用(javascript)那么只能够使用i和m,而x和s必须使用“$regex”

范例:查询以“谷”开头的姓名

db.student.find({"name":/谷/}).pretty()

注意/谷/不能带双引号,否则变字符串了。

范例:取出包含A的的姓名,不区分大小写。

db.student.find({"name":/a/i}).pretty()
db.student.find({"name":{"$regex":/a/i}}).pretty()

如果要执行模糊查询的操作,严格来讲只需要编写一个关键字就够了。

正则操作之中除了可以查询出单个字段的内容之外,也可以进行数组数据的查询。

范例:查询数组数据

db.student.find({"course":/语?/}).pretty()
db.student.find({"course":/语/}).pretty()

MongoDB中的正则符号和之前Java正则是有一些小小差别,不建议使用以前的一些标记,正则就将其应用在模糊数据的查询上。

4.2.10、数据排序

在MongoDB里面数据的排序操作使用“sort()”函数,在进行排序的时候可以有两个顺序:升序(1)、降序(-1)

范例:数据排序

db.student.find().sort({"score" : -1}).pretty()

但是在进行排序的过程里面有一种方式称为自然排序,按照数据保存的先后顺序排序,使用“$narutal”表示。

范例:自然排序

db.student.find().sort({"$natural" : -1}).pretty()

在MongoDB数据库里面排序的操作相比传统关系型数据库的设置要简单。

4.2.11、数据分页显示

在MongoDB里面的数据分页显示也是符合于大数据要求的操作函数:

      skip(n):表示跨过多少数据行;

      limit(n):取出的数据行的个数限制。

范例:分页显示(第一页,skip(0)、limit(5))

db.student.find().skip(0).limit(5).sort({"age":-1}).pretty()

范例:分页显示(第二页,skip(5)、limit(5))

db.student.find().skip(5).limit(5).sort({"age":-1}).pretty()

这两个分页的控制操作,就是在以后只要是存在有大数据的信息情况下都会使用它。

 

猜你喜欢

转载自blog.csdn.net/zlb_19850509/article/details/114465943
今日推荐