MongoDB详细数据操作
只要是数据库那么就绝对离不开最为核心的功能:CRUD。
数据的增加
使用“db.集合.insert()”可以实现数据的增加操作
范例:增加一个简单数据
> db.infos.insert({"url":"www.baidu.com"}) |
范例:保存数组
db.infos.insert([ {"url":"www.baidu.com"}, {"url":"www.baidujava.com"} ]); |
范例:保存10000个数据
for (var x = 0 ; x<10000 ; x++){ db.infos.insert({"url":"wenxudong-" + x}); } |
数据查询
在mongodb数据库里对于查询的支持非常到位有关系运算、逻辑运算、数组运算、正则运算
数据查询操作的核心语法:“db.集合名称.find({查询条件},[设置显示的字段])”
范例:查询固定的值得实例
db.infos.find{查询条件} |
对于设置的显示字段严格来讲就称为数据的投影操作,如果不需要显示的设置为0,需要显示的设置为1
db.infos.find({"url":"www.baidu.com"},{"_id":0}) |
db.infos.find({"url":"www.baidu.com"},{"_id":0,“url”:1}) |
对于这种投影操作的意义不大。同时对于数据的查询也可以使用“pretty()”函数进行漂亮显示。
范例:漂亮的显示
db.infos.find({"url":"www.baidu.com"},{"_id":0,“url”:1}).pretty() |
数据列多的时候一定可以看出华丽的效果
范例:查询单个数据
db.infos.findOne({"url":"www.baidu.com"},{"_id":0,“url”:1}) |
利用以上的查询可以实现格式化的输出效果
关系查询
在mongo里面支持的关系查询操作:大于($gt)、小于($lt)、小于等于($lte)、大于等于($gte)、等于(key:value、$eq)、不等于($ne)。但是想让这些操作可以正常使用,那么需要准备一个数据集合。
范例:定义一个学生信息集合
db.students.drop(); db.students.insert({"name":"张三","sex":"男","age":19,"score":89,"address":"松江区"}) db.students.insert({"name":"李四","sex":"女","age":20,"score":59,"address":"青浦区"}) db.students.insert({"name":"王五","sex":"女","age":21,"score":99,"address":"浦东新区"}) db.students.insert({"name":"赵六","sex":"男","age":20,"score":100,"address":"朝阳区"}) db.students.insert({"name":"孙七","sex":"男","age":19,"score":0,"address":"海淀区"}) db.students.insert({"name":"王八","sex":"女","age":19,"score":89,"address":"宝山区"}) db.students.insert({"name":"刘九","sex":"男","age":20,"score":69,"address":"长宁区"}) db.students.insert({"name":"钱十","sex":"女","age":21,"score":79,"address":"松江区"}) |
范例:查询姓名是张三的学生信息
db.students.find({"name":"张三"}).pretty(); |
范例:查询性别是男的学生信息
db.students.find({"sex":"男"}).pretty(); |
范例:查询年龄大于19岁的
db.students.find({"age":{"$gt":19}}).pretty(); |
范例:查询成绩大于等于60分的学生
db.students.find({"score":{"$gte":60}}).pretty(); |
范例:查询姓名不是王五的信息
db.students.find({"name":{"$ne":"王五"}}).pretty(); |
此时与之前最大的区别在于,在一个JSON结构里需要定义其它的JSON结构,并且这种风格在用程序进行操作的时候依然如此。
逻辑运算
逻辑运算主要三种类型:与($and)、或($or)、非($not、$nor)
范例:查询年龄在19~20岁的学生信息
db.students.find({"age":{"$gte":19,"$let":20 }}).pretty(); |
在进行逻辑运算的时候“and”的链接是最隐秘的,因为只需要利用“,”
范例:查询不是19岁的学生
db.students.find({"age":{"$ne":19}}).pretty(); |
范例:查询年龄大于19岁,或者成绩大于90分的学生
db.students.find({"$or" : [ {"age" : {"$gt":19}}, {"score" : {"$gt":90}}]}).pretty(); |
范例:也可以进行或的求反操作
db.students.find({"$nor" : [ {"age" : {"$gt":19}}, {"score" : {"$gt":90}}]}).pretty(); |
针对于或的操作可以实现一个求反的功能
在这几个逻辑运算之中,与的接最简单,而或的链接需要为数据设置数组的过滤条件。
求模
模的运算使用“$mod”来完成,语法“${mod:[数字,余数]}”。
范例:求模
db.students.find({"age":{"$mod":[20,1]}}).pretty(); |
利用求模计算可以编写一些数学的计算公式
范围查询
只要是数据库,必须存在有“$in”(在范围之中)、“$nin”(不在范围之中)
范例:查询姓名是张三 、 李四、 王五的信息
db.students.find({"name":{"$in":["张三","李四","王五"]}}).pretty(); |
范例:不在范围
db.students.find({"name":{"$nin":["张三","李四","王五"]}}).pretty(); |
在实际的工作之中,范围的操作很重要
数组查询
在MongoDB中是支持数组保存的,一旦支持了数组保存,就需要针对数组进行匹配
范例:添加数组
db.students.insert({"name":"gudashen - A","sex":"woman","age":21,"score":79,"address":"SongJiangQu","course":["Chinese","Math","English","Music","Politics"]}); db.students.insert({"name":"gudashen - B","sex":"女","age":21,"score":79,"address":"SongJiangQu","course":["Chinese","Math"]}); db.students.insert({"name":"gudashen - C","sex":"女","age":21,"score":79,"address":"SongJiangQu","course":["English","Music","Politics"]}); db.students.insert({"name":"gudashen - D","sex":"女","age":21,"score":79,"address":"SongJiangQu","course":[,"Math","English","Music","Politics"]}); db.students.insert({"name":"gudashen - E","sex":"女","age":21,"score":79,"address":"SongJiangQu","course":["Chinese","Music","Politics"]}); db.students.insert({"name":"gudashen - F","sex":"女","age":21,"score":79,"address":"SongJiangQu,"course":["Chinese","English","Music"]}); |
此时的数据包含的有数组内容,然后需要针对数组数据进行判断,可以使用几个运算符:$all、$size、$slice、$elemMatch
范例:同时参加语文和数学课程的学生
现在两个数组内容都需要保存,所以使用“{“$all”,[内容1,内容2]}”
db.students.find({"cuorse":{"$all":["Chines","Math"]}}).pretty(); |
“$all”计算可以用于数组上也可以用于一个数据的匹配上
范例:查询学生地址是“朝阳区”信息
db.students.find({"adress":{"$all":["ChaoYangQu"]}}).pretty(); |
既然在集合里保存的是数组信息,那么数组就可以利用索引操作,使用”key.index”的方式来定义索引
范例:查询数组中第二个内容(index=1,索引从0开始)
db.students.find({"course.1":"Math"}).pretty(); |
范例:查询出只参加两门课程的学生
使用 $size 来进行数量的控制
db.students.find({"course":{"$size":2}}).pretty(); |
发现以上查询时,数组的内容就全部显示出来了,现在控制数组返回的数量,那么可以使用“$slice”进行控制
范例:返回年龄为19岁所有学生的信息,但是只显示两门参加课程
db.students.find({"age":19},{"course":{"$slice":2}}).pretty(); |
现在只是取得前两门的信息,那么也可以设置负数表示取出后两门的信息
db.students.find({"age":19},{"course":{"$slice":-2}}).pretty(); |
或者只是取出中间部分的信息
db.students.find({"age":19},{"course":{"$slice":[1,1]}}).pretty(); |
上面的数据里第一个数据表示跳过的数据量,而第二个表示返回的数量
嵌套集合运算
在MongoDB数据里面每一个集合数据可以保存其它的集合数据
db.students.insert({"name":"wenxudong - A","sex":"woman","age":21,"score":79,"address":"SongJiangQu", "course":["Chinese","Math","English","Music","Politics"], "parents":[ {"name":"A(baba)","age":50,"job":"工人"}, {"name":"A(mama)","age":46,"job":"职员"}]}); db.students.insert({"name":"wenxudong - B","sex":"女","age":21,"score":79,"address":"SongJiangQu", "course":["Chinese","Math"], "parents":[ {"name":"B(baba)","age":50,"job":"处长"}, {"name":"B(mama)","age":46,"job":"局长"}]}); db.students.insert({"name":"wenxudong - C","sex":"女","age":21,"score":79,"address":"SongJiangQu", "course":["English","Music","Politics"], "parents":[ {"name":"C(baba)","age":50,"job":"工人"}, {"name":"C(mama)","age":46,"job":"处长"}]}); db.students.insert({"name":"wenxudong - D","sex":"女","age":21,"score":79,"address":"SongJiangQu", "course":[,"Math","English","Music","Politics"], "parents":[ {"name":"D(baba)","age":50,"job":"经理"}, {"name":"D(mama)","age":46,"job":"局长"}]}); |
嵌套集合的数据判断只能通过“$elemMatch”完成
范例:查询父母是局长的信息
db.students.find({"$and":[ {"age":{"$gte":19}}, {"parents": {"$elemMatch":{"job":"局长"}} } ]}).pretty(); |
判断某个字段是否存在
使用“$exists”可以判断某个字段是否存在,如果设置为true表示存在,设为false表示不存在
范例:查询具有parents成员的数据
db.students.find({"parents":{"$exists":true}}).pretty(); |
范例:查询不具有course程序的数据
db.students.find({"course":{"$exists":false}}).pretty(); |
条件过滤
关系型数据库有where,MongoDB里也有$where
范例:使用where进行数据查询
db.students.find({"$where":"this.age>20"}).pretty(); |
db.students.find("this.age>20").pretty(); |
|
对于“$where”是可以简化的,是属于每一行的信息判断,实际上对于数据量较大的情况并不方便使用。实际上以上的代码严格来讲是属于编写一个惭怍函数
db.students.find(function(){ return this.age>20; }).pretty(); |
当进行多个条件判断时
db.students.find({"$and":[ {"$where":"this.age>19"}, {"$where":"this.age<21"} ]}).pretty() |
虽然这种形式的操作可以实现数据查询但是最大的缺点是将MongoDB的Bson数据转换为js的语法结构,这样方式不方便使用数据库的索引机制。
正则运算
如果想要实现模糊查询,那么必须使用正则表达式,而且正则表达式使用的是语言Perl兼容的正则表达式的形式。如果要想实现正则使用,则按照如下的定义格式
- 基础语法:{key:正则标记};
- 完整语法:{key:{“$regex”:正则标记,“$options”:选项}}。
a) 对于options主要是设置正则的信息查询的标记
i. “i”:忽略字符大小写
ii. “m”:多行查找
iii. “x”:空白字符串除了被转义的或在字符类中意外的完全被忽略
iv. “s”:匹配所有的字符(圆点“.”),包括换行字符
b) 需要注意的是,如果是直接使用(javascript)那么只能够使用i和m,而“x”和“s”必须使用“$regex”
范例:查询以“谷”开头的姓名
db.students.find({"name":/Gu/}).pretty() |
范例:查询姓名有字母A的
db.students.find({"name":/a/i}).pretty() |
db.students.find({"name":{"$regex":/a/i}}).pretty() |
如果要执行模糊查询的操作,严格来讲只需要编写一个关键字就够了。
正则操作之中除了可以查询出单个字段的内容之外,也可以进行数组数据的查询
范例:查询数组
db.students.find({"course":/Chin/}).pretty() |
db.students.find({"course":/Chin?/}).pretty() |
MongoDB的正则与java有区别,不建议用以前的,这个正则就用在模糊数据查询上
数据排序
在MongoDB里面数据的派讯操作使用“sort()”函数,在进行排序的时候有两个顺序:升序(1)、降序(-1)
范例:成绩数据排序
db.students.find().sort({"score":-1}).pretty() |
但是在排序的过程里有一种方式称为自然排序,按照数据保存的先后顺序排序,使用“$natural”表示
范例:自然排序
db.students.find().sort({"$natural ":-1}).pretty() |
MongoDB数据库比传统关系型数据库设置排序要简单
数据分页显示
skip(n):表示瓜果多少行数据
limit(n):取出的数据行的个数限制。
范例:分页显示
db.students.find().skip(0).limit(5).sort({"age":-1}).pretty() |
数据更新操作
db.students.find().skip(0).limit(5).sort({"$natural":1}).pretty();
在MongoDB里面对于数据的更新操作提供了两类函数:save()、update()。
函数的基本使用
如果要修改数据最直接的使用函数就是update()函数,但是这个函数的语法要求很麻烦。
1. 语法:db.集合.update(更新条件,新的对象数据,upsert,multi);
a) upsert:如果要更新的数据不存在,则增加一条新的内容(true为增加,false为不增加)
b) multi:表示是否只更新满足条件的第一行记录,如果设置为false,只更新第一条,如果是true全部更新
范例:更新存在的数据--将年龄是19岁的人的成绩改为100分(此时会返回多条数据)
只更新一条数据
db.students.update({"age":19},{"$set":{" score":100}},false,false); |
所有满足条件的数据都更新
db.students.update({"age":19},{"$set":{" score":100}},false,true); |
范例:更新不存在的数据
db.students.update({"age":30},{"$set":{"name":不存在}},true,false); |
因为没有该信息所以进行了数据创建
save()函数的功能与更新不存在的内容相似
范例:save()函数操作
需要通过_id来修改增加数据。 |
修改器
对MongoDB数据库而言,数据的修改会牵扯到内容的变更、结构的变更(包含有数组),所以在进行MongoDB设计的时候就提供有一系列的修改器的应用,那么像之前使用的“$set”就是一个
1. $inc:主要针对于一个数字字段,增加某个数字字段的数据内容:
a) 语法:{“$inc”:{“成员”:内容}}
范例:将所有年龄为19岁的学生成绩一律减少30分
db.students.update({"age":19},{"$inc":{"score":-30,"age":1}}); |
db.students.update({"age":19},{"$inc":{"score":-30,"age":1}},false,true); |
$set:进行内容的重新设置。
a) 语法:{“$ set”:{“成员”:新内容}}
范例:将年龄是20岁的人成绩修改为90
db.students.update({"age":20},{"$set":{"score":90}}); |
$unset:删除某个成员的内容。
a) 语法:{“$unset”:{“成员”:1 }}
范例:删除zhangsan的年龄与成绩信息
db.students.update({"name":"zhangsan"},{"$unset":{"age":1,"score":1}}) |
执行之后指定的成员内容就消失了
$push:相当于将内容追加到指定的成员之中(基本上是数组)
a) 语法:{“$push”:{“成员”:value}}
范例:向zhangsan添加课程信息(此时zhangsan信息下没有course信息)
db.students.update({"name":"zhangsan"},{"$push":{"course":"Chinese" }}); |
范例:想“gudashen - D”里面的课程添加一个信息
db.students.update({"name":"gu…. "},{"$push":{"course":"MeiShu" }}); |
就是进行数组数据的添加操作使用的,如果没有数组则创建数组,有则追加。(一次添加一个)
$pushAll:与$push类似,可以一次追加多个内容到数组里面;
a) 语法:{“$pushAll”:{“成员”:数组内容}}
范例:想wangwu的信息里面添加多个课程内容
db.students.update({"name":"wangwu"},{"$pushAll":{"course":["Chinese","Math","MeiShu"] }}); |
$addToSet:想数组里面增加一个新的内容,只有内容不存在时再添加
a) 语法:{“$ addToSet”:{“成员”:内容}}
范例:向王五的信息增加新内容
db.students.update({"name":"wangwu"},{"$addToSet":{"course":"Chinese" }}); |
db.students.update({"name":"wangwu"},{"$addToSet":{"course":"TiaoWu" }}); |
先判断内容是否存在,如果不存在则向数组之中追加内容,如果存在则无操作
$pop:删除数组内的数据
a) 语法:{“$ pop”:{“成员”:内容}},内容为1删除最后一个,内容为-1删除第一个
范例:删除王五的一个课程
db.students.update({"name":"wangwu"},{"$pop":{"course":-1 }}); |
$pull:从数组内删除一个指定内容的数据
a) 语法:{“$ pull”:{“成员”:数据}}
db.students.update({"name":"wangwu"},{"$pull":{"course":"Math" }}); |
$pullAll:一次性删除多个内容
a) 语法:{“$ pullAll”:{“成员”:[数据1,数据2…]}}
范例:删除谷大神 – A 中的三门课程
db.students.update({"name":"gudaA…"},{"$pullAll":{"course":["Math","Chiaese","Muice"] }}); |
|
$rename:为成员名称重命名
a) 语法:{“$ rename”:{“成员”:新的成员名称 }}
范例:将“张三”name成员名称修改为“姓名”
db.students.update({"name":"wangwu"},{"$rename":{"name":"姓名" }}); |
|
删除数据
remove()函数进行删除
但是这个函数有两个可选项
删除条件:满足条件的数据被删除
是否只删除一个数据,如果设置为true或者是1表示只删除一个
范例:删除所有姓名里面带有Gu的信息
db.students.remove({"name":/Gu/}) |
范例:删除姓名带有“高”的信息,要求只删除一个
db.students.remove({"name":/高/},true); |
范例:清空infos集合中的内容
db.infos.remove({}); |
游标
MOngoDB中控制游标只需要find()函数就可以返回由游标了。对于返回的游标如果想要进行操作,则可以使用两个函数:
- 判断是否有下一行数据:hasNext();
- 取出当前数据:next();
var cursor = db.students.find(); cursor.hashNext(); cursor.next(); |
以上是游标的操作形式,但是实际不能这么去用,因为必须利用循环才能够输出内容。
范例:操作循环
var cursor = db.students.find(); while(cursor.hasNext()){ var doc = cursor.next(); print(doc.name); } |
当有表数据取出来之后输出的是Object类型,那么如果需要将数据按照json的形式出现,则可以使用printjson()函数来完成。
var cursor = db.students.find(); while(cursor.hasNext()){ var doc = cursor.next(); printjson(doc); } |
注:本文整理来自于视频教学。