mongoDB数据库学习总结
基本概念与安装
mongo > 非关系性数据库 > 集合 > 文件
- Windows 用户向导:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/
- Linux 用户向导:https://docs.mongodb.com/manual/administration/install-on-linux/
- Mac 用户向导:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/
可视化的mongo
数据库工具推荐:MongoChef 是另一款强大的MongoDB
可视化管理工具,支持Windows
、Linux
和Mac
。
基本的shell
操作
|
|
使用js
脚本来编写mongoShell
命令
本质就是mongo
支持直接通过脚本文件来执行一系列的命令,并且在这个脚本中默认注入了一些方法,如connect
等
|
|
把以上代码保存为jsTask.js
, 在命令行中使用mongo jsTask.js
即可 或者load('./jsTask.js')
如果db.name.insert()
的参数是一个元素为json对象的数组,则是批量插入
update
修改器用法
在实际应用中,由于修改操作与关系性数据库不同,容易覆盖之前的所有数据,因此引入了修改器关键字,在此重点介绍
update()
这个方法可以传入第三个参数,第三个参数可以理解为options
的对象
|
|
- 单文件修改
$set
修改器,用于修改指定的键值:
db.workmate.update({"name":"MinJie"},{$set:{"sex":2,"age":21}})
上面这条命令就可以把MinJie
这条数据对应的sex
和age
的键值给更新了,其他内容保持不变。
db.workmate.update({"name":"MinJie"}, {$set:{skill.skillThree:"PPT"}})
这条命令说明$set
支持通过.
符号来修改更新内嵌的对象内容
$unset
修改器,用于删除指定的键:
db.workmate.update({"name":"MinJie"}, {$unset:{"age":''}})
$inc
数字修改器,只针对数字项的计算修改,如在原来数字基础上减去5:
db.workmate.update({"name":"MinJie"}, {$inc:{"age":-5}})
options
中的两个参数multi
和upsert
:
db.workmate.update({name:'xiaoWang'},{$set:{"age":20}},{upsert:true})
用于更新集合中的键值对时,如果不存在此键,则执行插入操作,默认是不插入
db.workmate.update({}, {$set:{"interest":[]}}}, {multi: true})
用于在向表中更新新的键名时,使之应用于全部的文件,使每条数据都发生更改
注意简写:update的默认第三个参数表征upsert
, 第四个参数表征multi
- 数组批量修改
$push
修改器,用于追加数组/内嵌文档值:
为数组类型的键增加值 db.workmate.update({name:'xiaoWang'}, {$push:{"interest":'draw'}})
为内嵌文档内容增加值 db.workmate.update({name:'xiaoWang'}, {$push:{"skill.skillFour":'draw'}})
$addToSet
修改器,当数组中不存在要更新的值时再触发追加操作:
用法示例(已经有draw
则不触发) db.workmate.update({name:'xiaoWang'}, {$addToSet:{"interest":'draw'}})
使用$ne
的等效语句 db.workmate.update({name:'xiaoWang',"interest":{$ne:'draw'}},{$push:{"interest":'draw'}})
$each
数组修改器,用于一次性插入多个数据到数组中:
现在要给xiaoWang,一次加入三个爱好,唱歌(Sing),跳舞(Dance),编码(Code):
|
|
$pop
数组删除修改器,通过传参数来决定从数组首位(-1)还是末尾(1)删除:
删除最后一个兴趣 db.workmate.update({name:'xiaoWang'},{$pop:{"interest":1}})
数组定位修改可以用类似内嵌文档的语法:
把第二个兴趣值改成读书 db.workmate.update({name: 'xiaoWang'}, {$set:{"interest.1":'read'}})
应答式操作的修改方式
应答式写入就会给我们直接返回结果(报表),结果里边的包含项会很多,从而可以灵活地根据上一步的结果来决定下一步的结果
- 之前的所有内容都是非应答式操作,也就是操作完之后没有反馈,并不知道是否成功
- 需要引入
db.runCommand()
这个执行器,用于包裹执行命令,然后可以根据返回内容判断是否操作成功。 db.listCommonds()
用于看执行器可以执行的命令,如db.runCommand({ping:1})
看数据库链接是否成功findAndModify
也是执行器的命令之一,可以用于查找并触发删除或者修改等动作并通过执行器反馈,示例如下
|
|
findAndModify
可用的属性值:
- query:需要查询的条件/文档
- sort: 进行排序
- remove:[boolean]是否删除查找到的文档,值填写
true
,可以删除。(与update
不可共存) - new:[boolean]返回更新前的文档还是更新后的文档。
- fields:需要返回的字段
- upsert:没有这个值是否增加。
接下来的课程的所有涉及删除和更新的操作都会用到findAndModify
这个功能,从而保持数据操作的严谨性。
find
命令来查找数据
find
操作是数据库最常用的查询命令,其语法与关系性数据库差异是最大的,用例子来讲方便入手
db.workmate.find({"skill.skillOne":"HTML+CSS"}, {name: 1, _id: 0, job: 1})
find
的第一个参数是要查询的query
,后面的对象参数是指定返回来的字段,默认是全返回,_id
是这条数据的默认key
键,默认返回,如果不需要返回需指定此项是0
或false
,其他项需返回,则要指定为1
或true
。
db.workmate.find({age:{$lte:30,$gte:25}},{name:true,age:true,"skill.skillOne":true,_id:false})
上面这个命令用于查找出年龄大于25小于30的同事,这里用到了不等修饰符
- 小于($lt):英文全称
less-than
- 小于等于($lte):英文全称
less-than-equal
- 大于($gt):英文全称
greater-than
- 大于等于($gte):英文全称
greater-than-equal
- 不等于($ne):英文全称
not-equal
|
|
上面的命令用于找出注册时间大于1月1日的数据,可以看出用时间来比较很方便。
find
同样支持多条件查询,其对应的关键字为:$and、$or、$not
这三个
|
|
find
的数组查询,即当储存的某一个键的值是数组时,有额外的查询方法和技巧
现在我把之前的数据结构加以改变,增加一个interests
数组类的储存
基本查询(很少用,得知概念即可):
不带中括号的查询:为只要这一项是待匹配数据的数组中有的,就会找出来,常用的是tag
标示。
db.workmate.find({interest:'看电影'}, {name:1,interest:1,age:1,_id:0})
带中括号的查询:必须是数组中的元素完全匹配才能找出来,也就是必须完全一致
db.workmate.find({interest:['画画','聚会','看电影']}, {name:1,interest:1,age:1,_id:0})
$all
-数组多项查询,用于同时查询数组中多个元素,类似非数组中的$and
,但用法不同$in
-数组或查询,用于用多个元素来筛选数据,类似非数组中的$or
,但用法不同$size
-数组数量查询,用于指定查出数组的长度为指定值的数据,数组查询特有$slice
-非查询指令,用于指定数组项的返回个数,用在第二个参数中,如显示前两项等要求
|
|
学习使用
find
命令进行分页查询之前,首先看一下如何编写js
脚本来进行数据查询,本质就是赋值后循环打印
使用forEach
方法:
|
|
使用hasNext+while
的方法:
|
|
接下来就可以尝试通过写脚本来完成查询数据库的操作啦
分页查询指令的学习,可以使用类似函数式的链式调用,可读性很强
find
参数:
query
:这个就是查询条件,MongoDB默认的第一个参数。fields
:(返回内容)查询出来后显示的结果样式,可以用true和false控制是否显示。limit
:返回的数量,后边跟数字,控制每次查询返回的结果数量。skip
:跳过多少个显示,和limit结合可以实现分页。sort
:排序方式,从小到大排序使用1,从大到小排序使用-1。
使用传参数操作的脚本:
|
|
链式操作脚本:
|
|
$where
操作符,可以通过js
语法来查询,方便,但要慎用,安全性和性能较低
|
|
mongoDB数据库权限管理
对于数据库,我们有必要根据不同的用户赋予不同的权限,还有设置用户名和密码,以及鉴权等操作,看一下基本的命令
首先进入admin
库中,进入方法是直接使用use admin
就可以。
进入后可以使用show collections
来查看数据库中的集合。默认是只有一个集合的system.version
。
新建用户的脚本:
|
|
内置角色(了解即可):
- 数据库用户角色:read、readWrite;
- 数据库管理角色:dbAdmin、dbOwner、userAdmin;
- 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManage;
- 备份恢复角色:backup、restore;
- 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
- 超级用户角色:root
- 内部角色:__system
查找和删除用户(user加s):
db.system.users.find()
db.system.users.remove({user: 'karl'})
mongoDB
的鉴权操作:db.auth("karl", "123456")
成功返回1,失败返回0
关闭重启mongo
,以鉴权方式启动: mongod --auth
此后使用用户名和密码登陆后才能对mongo
进行操作
mongo -u karl -p 123456 127.0.0.1:27017/admin
然后就可以正常操作了
以上是对mongo
的操作进行权限保护,在工作中用后端应用连接数据库操作是一个很频繁且需要慎重的过程,因此这一块需要明确的认知
mongo
数据库的备份和恢复
这个工作大部分是
DBA
或者运维同学来操作,但如果做一个完整的项目,必须要有容错的手段和容灾备份。
mongodump
为数据备份的操作命令,其shell
中基本格式如下:
|
|
把当前Mongo
的库备份到D盘下的dataBack
文件夹(登陆者需要有相应的权限):
mongodump --host 127.0.0.1 --port 27017 --out D:/databack
备份好之后就可以用于数据库的还原了,还原数据库的命令是mongorestore
,在数据库出现意外时还原
|
|
使用命令进行恢复:mongorestore --host 127.0.0.1 --port 27017 D:/databack/
备份和恢复都可以做成脚本任务,备份可能需要运维定时间运行。脚本设置可以参考这里,需要有shell
基础。
数据库的索引
用于数据检索时,通过指定字段建立对应索引值,从而在检索
find
的命令执行时,相应字段的检索效率会成倍提升。
显示索引: db.randomInfo.getIndexes()
会发现_id
是唯一的索引
|
|
为集合添加索引: db.randomInfo.ensureIndex({username:1})
把用户名建立索引,通过用户名来检索的速度提升
删除索引(): db.randomInfo.dropIndex('randNum0_1');
这里需要注意的是删除时填写的值,并不是我们的字段名称(key
),而是我们索引查询表中的name
值。
如果复合查询的两个字段都建立了索引,可以通过hit
方法来指定以何种字段优先检索:
var rs= db.randomInfo.find({username:'7xwb8y3',randNum0:565509}).hint({randNum0:1});
整个简易教程到此结束,希望对入门mongoDB
的人有一定帮助和借鉴~