版本4.0.5
1、数据的增加
db.infos.insert();
a. 增加简单的数据:
db.infos.insert({"url":"www.baidu"});
b. 增加数组:
db.infos.insert(
[
{"url":"www.baidu.com"},
{"url":"www.jingdong.com"}
]
);
如果想要保存多个数据,name就使用数组。
c. 保存10000个数据?
for(var x = 0;x<10000;x++){
db.infos.insert(
{"url":"the number is =" + x}
);
}
如果数据保存很多的情况下,列表是不会全部列出的,它只会列出部分的内容。
2. 数据的查询
任何的一个数据库之中,查询是最为麻烦的。而在Mongo数据库里面,对数据库查询的支持都非常到位,包含有逻辑运算,关系运算、数组运算、正则运算等等。
首先对于数据的查询操作的核心的语法:“db.集合名称.find({查询条件[,{设置显示的字段}]})”。
例:最简单的用法就是直接使用find()函数完成查询
db.infos.find();
例:希望查询url为www.baidu 的一条数据
db.infos.find({"url":"www.baidu"});
发现在进行数据查询的时候也是按照JSON的形式设置的相等关系。它的整个开发之中都不可能离开JSON数据。
对于设置的显示字段严格来讲就称为数据的投影操作。如果不需要显示的字段设置“0”,需要显示的字段设置“1”。
例:不想显示“_id”
db.infos.find({"url":"www.baidu"},{"_id":0})
db.infos.find({"url":"www.baidu"},{"_id":0,"url":1})
大部分的情况下,这种投影操作的意义不大。同时对于数据的查询也可以使用“pretty()”函数进行漂亮显示。
例:漂亮显示
db.infos.find({"url":"www.baidu"},{"_id":0}).pretty();
据说数据列多的时候可以显示出华丽的显示效果。
例:查询单个数据
db.infos.findOne({"url":"www.baidu"},{"_id":0});
利用以上的查询可以实现格式化的输出效果,前提:列的内容必须很多。
1.关系运算
Mongo数据库中支持的关系查询操作:大于($gt)、小于($lt)、大于等于($gte)、小于等于($lte)、不等于($ne)、等于(key:value、eq);但是要想让这些操作可以正常使用,那么需要准备出一个数据集合。
db.students.drop();
db.students.insert(
[
{"name":"张一","sex":"男","age":"19","score":89,"address":"海淀区"},
{"name":"张二","sex":"女","age":"20","score":67,"address":"朝阳区"},
{"name":"张三","sex":"男","age":"21","score":78,"address":"大丰区"},
{"name":"张四","sex":"男","age":"22","score":60,"address":"房山区"},
{"name":"张五","sex":"女","age":"23","score":20,"address":"东城区"},
{"name":"张六","sex":"男","age":"21","score":33,"address":"西城区"},
{"name":"张七","sex":"男","age":"20","score":46,"address":"海淀区"},
{"name":"张八","sex":"女","age":"20","score":19,"address":"西城区"},
{"name":"张九","sex":"男","age":"19","score":54,"address":"海淀区"},
{"name":"张是","sex":"男","age":"29","score":83,"address":"通州区"}
]
);
例:查询姓名为张三的学生。
db.students.find({"name":"张三"});
db.students.find({"name":"张三"}).pretty();
例:查询性别是男的学生。
db.students.find({"sex":"男"});
例:查询年龄大于20的学生。注意引号,我这里年龄加了引号。
db.students.find({"age":{"$gt":"20"}});
例:查询年龄小于等于20 的学生。
db.students.find({"age":{"$lte":"20"}});
例:查询姓名不是张三的学生。
db.students.find({"name":{"$ne":"张三"}});
附加:cls 命令清屏。
此时与之前最大的区别就在于,在一个JSON结构里面定义其他的JSON结构,并且这种风格在我们日后通过程序进行操作的时候依然如此。
2、逻辑运算
逻辑运算主要就是三种类型:与(“$and”)、或(“$or”)、非(“$not、$nor”)
例:查询年龄在19到20之间的学生。
db.students.find({"age":{"$gte":"19","$lte":"20"}});
在进行逻辑运算的时候“and”的连接是最容易的,因为只需要利用“,”逗号,分割若干个条件就可以。
但是本人自己在用的时候没有成功。
例
db.students.find({"$and":[{"age":"19"},{"name":"李五"}]});
db.students.find({"age":"19"},{"name":"李五"});
非的话,($ne)
例:年龄大于20岁,或者成绩大于60的学生
db.students.find(
{"$or":[
{"age":{"$gt":"20"}},
{"score":{"$gt":60}}
]}
);
例:年龄不大于20岁,或者成绩不大于60 的学生
db.students.find(
{"$nor":[
{"age":{"$gt":"20"}},
{"score":{"$gt":60}}
]}
);
针对于或的操作可以实现一个求反的功能。
在这几个逻辑运算中与的连接最简单,而或的连接需要为数据设置数组的过滤条件。
3.模运算
模的运算使用“$mod”来完成,语法“{$mod:[数字,余数]}”
例:求模,
# 对二取余,余数为1的,也就是奇数
db.students.find({"score":{"$mod":[2,1]}});
# 对二取余,余数为0的,也就是偶数
db.students.find({"score":{"$mod":[2,0]}});
利用求模计算可以编写一些数学的计算公式。
4.范围查询
只要是数据库,必须存在有“$in”(在范围之中)、或者“$nin”(不在范围之中)
例:查询姓名为张一、张三、张五的学生
# 在范围查询
db.students.find({"name":{"$in":["张一","张三","张五"]}});
# 不在范围查询
db.students.find({"name":{"$nin":["张一","张三","张五"]}});
在实际工作中,范围的操作很重要。
5、数组查询
首先在mongodb里面支持数组保存,一旦支持了数组保存,就需要针对数组的数据进行匹配。
例:保存一部分数组内容
db.students.insert(
[
{"name":"李毅","sex":"男","age":"19","score":89,"address":"海淀区","course":["语文","数学"]},
{"name":"李五","sex":"女","age":"19","score":89,"address":"海淀区","course":["语文","英语"]},
{"name":"李二","sex":"女","age":"20","score":67,"address":"朝阳区","course":["英语","化学","生物"]},
{"name":"李三","sex":"男","age":"21","score":78,"address":"大丰区","course":["地理","政治"]},
{"name":"李四","sex":"男","age":"22","score":60,"address":"房山区","course":["体育","美术","音乐"]}
]
);
此时的数据包含有数组内容,而后需要针对于数组数据进行判断,可以使用几个运算符:$all、$size、$elemMatch
例:查询同时参加语文数学课程的学生。
现在两个数组内容都需要保存,所以使用“{"$all":[内容1,内容2]}”
db.students.find({"course":{"$all":["语文","数学"]}});
db.students.find({"course":{"$all":["数学","语文"]}});
发现数组内内容的顺序无影响。且,只有一个数据符合的也不会显示。
虽然“$all”计算可以用于数组上,但是也可以用于一个数据的匹配上。
例:查询学生地址是海淀区的。
db.students.find({"address":{"$all":["海淀区"]}});
既然在集合里面现在保存的是数组信息,那么数组就可以利用索引操作,使用“Key.index”的方式来定义索引。
例:查询数组中第二个内容(index = 1,索引下表从0开始)为数学的信息。
db.students.find({"course.1":"数学"});
例:查询出只参加两门课程的学生。
使用“$size”来进行数量的控制。
db.students.find({"course":{"$size":2}});
发现子啊进行数据查询的时候,只要内容符合条件,数据就全部查询出来了。现在希望可以控制查询返回的数量。
那么我们可以使用($sllice)进行控制。
例:返回年龄为19岁的学生并且参加两门的课程。这里有问题一直没有成功。
db.students.find({"age":"19"},{"course":{"$slice":2}});
$slice:1 为数组的第一个,-1为数组的倒数第一个,[x,y]是从x到y个数据。这里有问题,与操作没成功。
查询了官网,按官网给的例子也没有成功。郁闷。
6、嵌套集合运算
在MongoDB数据里面每一个集合数据可以保存其他的集合数据,例如:有些学生需要保存家长信息。
例:增加信息
db.students.insert(
{
"name":"王一",
"sex":"男",
"age":"23",
"score":56,
"address":"山东",
"course":["语文","数学","英语","物理"],
"parents":[
{"name":"王一父亲","age":"56","job":"设计师"},
{"name":"王一母亲","age":"57","job":"经理"}
]
}
);
7、判断某个字段是否存在
使用“$exit”判断某个字段是否存在。如果设置为true表示存在,设置fals表示不存在。
例如:查询具有parents成员的数据。
db.students.find({"parents":{"$exists":true}}).pretty();
例:查询不具有course的学生
db.students.find({"course":{"$exists":false}}).pretty();
可以利用此类查询来进行一些不需要的数据的过滤。
8、条件过滤
实际上习惯于传统开发关系型数据库开发的我们对于,数据的一定想到的是where,MongoDB里面也提供“$where”
例:使用$where 进行数据的查询
db.students.find({"$where":"this.age>22"}).pretty();
db.students.find("this.age>22").pretty();
对于$where 是可以简化的,但是这类的操作是属于进行每一行的信息判断,实际上对于数据量较大的情况并不方便使用。实际上以上的代码严格来讲是属于编写一个操作的函数。
db.students.find(function(){
return this.age>22
}).pretty();
db.students.find({"$where":function(){
return this.age>22
}}).pretty();
以上只是查询了一个判断,如果要想实现多个条件的判断,那么久需要使用and连接。
db.students.find({"$and":[{"$where":"this.age>19"},{"$where":"this.age<22"}]}).pretty();
虽然这种形式的操作可以实现数据查询,但是最大的缺点是将在MongoDb里面保存的BSON我们重新变为了javaScript的语法结构,这样的方式不方便使用数据库的索引机制。
9、模糊查询(正则运算)
如果要想实现模糊查询。那么必须使用正则表达式,而正则表达式使用的是语言Perl兼容的正则表达式的形式。如果要想实现正则的使用,则按照如下的格式:
基础语法:{key:正则标记};
完整语法:{key:{"$regex":正则标记,"$options":选项}}。
对于options主要是这只正则的信息查询的标记;
“i” :忽略字母大小写;
“m”:多行查找;
“x”:空白字符串除了被转义的或在字符类中意外的完全被忽略。
“s”:匹配所有的字符(圆点、“.”),包括换行内容。
需要注意的是,如果是直接使用(javascript)那么只能使用“i”和“m”,而“x”和“s”必须使用“$regex”。
例:查询以 “李” 开头的姓名
db.students.find({"name":/李/}).pretty();
我查询的时候发现,查小写字母和加 i 一样的情况
例:查询以a开头的学生
# 添加
db.students.insert([
{
"name":"Adma",
"age":"25",
"sex":"男"
},
{
"name":"alike",
"age":"23",
"sex":"女"
}
]);
# 查询
db.students.find(
{
"name":/a/i
}
).pretty();
# 完整的写法
db.students.find(
{
"name":{
"$regex":/a/i
}
}
).pretty();
小写不加i的时候
db.students.find(
{
"name":/a/
}
).pretty();
大写不加 i 查
db.students.find(
{
"name":/A/
}
).pretty();
大写加 i 查
db.students.find(
{
"name":/A/i
}
).pretty();
如果进行模糊查询,严格来说只需要编写一个关键字就够了。
正则操作除了可以单个查询字段之外,也可以进行数组数据的查询。
例查询数组数据
db.students.find(
{
"course":/语/
}
).pretty();
db.students.find(
{
"course":/语/?
}
).pretty();
MongoDB中的正则和java中的正则是有一些小小的区别的。不建议使用以前的
一些标记,正则就将其运用在模糊数据的查询上就完了。
10、数据排序
在MongoDB中排序只用 "$sort()" 函数,在进行排序的时候可以有两个顺序:升序(1)、降序(-1)。
例:顺序排序,成绩按降序排序
db.students.find().sort({"score":-1}).pretty();
但是在排序的过程里面有一种方式称之为自然排序,按照数据保存的先后顺序排序。使用 “$natural” 表示。
例:
db.students.find().sort({"$natual":-1}).pretty();
在MongoDB数据库里面排序的操作相比较传统关系型数据库要简单。
11、分页显示
在MongoDB里面的数据分页显示也是符合大数据要求的操作函数:
skip(n) : 跨过多少数据;
limit(n): 取出的数据行的个数限制;
例:分页显示。(第一页,跨过条,限制5条)按年龄排序
db.students.find().sort({"age":1}).pretty();
db.students.find().skip(0).limit(5).sort({"age":1}).pretty();
例:查询第二页
db.students.find().skip(5).limit(5).sort({"age":1}).pretty();
也两个分页控制操作,就是在以后是存在大数据的情况下,我们都会使用它。
3.4.3、数据更新操作
对于MongoDB而言,数据的更新基本上是一件很麻烦的事情,如果在实际的工作之中,真的具有此类的操作,那么最好的做法:在MongoDB里面对于数据的更新操作提供了两类函数:save() 和 update();
3.4.3.1、函数的基本使用
如果要修改数据最直接的使用函数就是update(),但是这个函数的语法要求很麻烦。
语法:db.集合.update(更新条件,新的对象数据,upsert,multi);
- upsert : 如果要更新的数据不存在则增加一条新的内容(true为增加,false为不增加)
- multi : 是否只更新满足条件的第一行记录。如果设置为false只更新第一条,如果设置为true,全部更新。
例: 性别为女的成绩都更新为100分。(此时会返回多条数据)
只更新第一条数据。
db.students.update({"sex":"女"},{"$set":{"sore":100}},false,false);
所有满足条件的数据都能更新。
db.students.update({"sex":"女"},{"$set":{"sore":100}},false,true);
例:更新不存在的数据
db.students.update({"age":"40"},{"$set":{"name":"不存在"}},true,false);
由于没有年龄是30岁的学生信息,所以此时相当于进行了数据的创建。
除了update的函数还有有一个save()函数,这个函数的功能与更新不存在的内容相似。
例使用save()操作。
修改存在的数据
db.students.save({"_id" : ObjectId("5c6fa3bdfbbdb92233274c9a"),"age":"65"});
修改不存在的数据
db.students.save({"_id" : ObjectId("aaafa3bdfbbdb92233274c9a"),"age":"69"});
如果要保存的数据存在了,就会变为更新操作,如果要保存的数据不存在,就变为了新增操作。
3.4.3.2、修改器
对于MonoDB数据库而言,数据的修改会牵扯内容的变更、结构的变更(包含有数组)。所以在进行MongoDB设计的时候就提供有一系列的修改器的应用,那么像之前使用的“$set”就是一个修改器。;
1.$inc :主要针对于一个数字字母,增加某个数字字段的数据内容;
语法:{“$inc”:{"成员":“内容”}}
例:将所有年龄为19的学生成绩一律减少30分。
db.students.update({"age":"19"},{"$inc":{"score":-30}});
2、$set: 进行内容的重新设置:
语法:{"$set":{"成员":“新内容”}};
例:将所有年龄是20岁的人的成绩改为89分。
db.students.update({"age":"19"},{"$set":{"score":89}});
3、$unset:删除某个成员的内容
语法:{"$unset":{"成员":"1"}}
例:删除“张三”的年龄与成绩信息。
db.students.update({"name":"张三"},{"$unset":{"age":1,"score":1}});
执行后指定的成员内容就消失了。
4、$push:相当于将内容追加到指定的成员之中(基本上是数组)
语法:${"push":{"成员":value}} ,value基本上是数组。
例:向李四的课程里面添加课程 语文 内容。
db.students.update({"name":"李四"},{"$push":{"course":"语文"}});
例:向张三添加课程信息(此时张三信息下没有course信息)
db.students.update({"name":"张三"},{"$push":{"course":["语文","数学"]}});
就是进行数组数据的添加操作使用的,如果没有数组,则进行一个新的数组的创建,如果有则进行数据的追加。
5、$pushAll :与 $push 是类似的,可以一次追加多个内容到数组里面;
语法:${"$pushAll":{成员:数组内容}}
本人没有成功,网上查 了发现。
mongodb很早前的版本就合并了$push和$pushAll,然后mongodb 3.6取消了$pushAll所以要么mongodb降级到3.4,要么mongoose升级到5.0 rc2试试。
6、$addToSet :向数组里面增加一个内容,只有这个内容不存在的时候才增加。
语法:{“$addToSet”:{成员:内容}。}
db.students.update({"name":"李三"},{"$addToSet":{"course":["地理","政治"]}});
db.students.update({"name":"李三"},{"$addToSet":{"course":"地理"}});
db.students.update({"name":"李三"},{"$addToSet":{"course":"语文"}});
此时会判断要增加的内容在数组里面是否已经存在了,如果不存在则想数组中追加内容,如果存在了则不做任何修改操作。
7、$pop :删除数组内的数据
语法:{"$pop":{成员:内容}},内容如果设置为-1表示删除第一个,如果是1表示删除最后一个。
例:删除李三的第一个课程
db.students.update({"name":"李三"},{"$pop":{"course":-1}});
例:删除李三的最后一个课程
db.students.update({"name":"李三"},{"$pop":{"course":1}});
8、$pull : 从数组内删除一个指定内容的数据
语法:{"$pull":{成员:数据}},,如果是此数据删除
db.students.update({"name":"李三"},{"$pull":{"course":"美术"}});
db.students.update({"name":"李三"},{"$pull":{"course":"政治"}});
9、$pullAll 一次性删除多个内容
语法:{"$pullAll":{成员:[数据,数据……]}}
例:删除李九十中的两门课程
db.students.update({"name":"李九十"},{"$pullAll":{"course":["语文","英语"]}});
10、$rename:为成员名称重命名
语法:{"$rename":{旧的成员名称:新的成员名称}}
db.students.update({"name":"李九十"},{"$rename":{"name":"姓名"}});
在整个的MongoDB数据库里面,提供的修改器的支持很到位。
3.4.4、删除数据
在MongoDB里面数据的删除实际上并不复杂,只需要使用“remove()”
但是这个函数是有两个可选项的:
1.删除条件:满足条件的数据被删除;
2.是否只删除一个数据,如果设置为true或者1,表示只删除一个
例:【废弃】清空infos集合中的内容
db.infos.remove(); 据说2.*版本可以用
db.infos.remove({});
删除集合
db.infos.drop();
例、删除姓名里面带有三的
db.students.remove({"name":/三/});
例:删除姓名带有二的信息,要求删除一个
db.students.remove({"name":/二/},true);
删除操作里面依然需要使用限定查询的相关操作内容。
3.5、游标
所谓的游标就是指数据可以一行行的操作,非常类似于ResultSet数据处理。在MongoDB的数据库中对于游标的控制非常简单,只需要使用find()函数就可以返回游标了。对于返回的游标,如果想要进行操作,则可以通过两个函数
1.判断是否有下一行数据:hasNext();
2. 取出当前数据:next();
var cursor = db.students.find();
cursor.hasNext();
cursor.next();
以上是游标的操作形式,但实际上不可能这么去用。因为必须利用循环才能输出内容
例:编写具体的操作代码
var cursor = db.students.find();
while(cursor.hasNext()){
var doc = cursor.next();
print(doc.name);
}
相当于每一个数据都单独拿出来进行逐行的操作。当游标数据取出来之后,实际上每行内容都是一个object数据,如果需要将数据按照json的形式出现,则可以使用printjson(0函数
var cursor = db.students.find();
while(cursor.hasNext()){
var doc = cursor.next();
print(doc);
}
var cursor = db.students.find();
while(cursor.hasNext()){
var doc = cursor.next();
printjson(doc);
}
在所有的已知数据库中,只有MongoDB的游标操作最简单,最直观。