文章目录
MongoDB基本操作
基本概念
生活中:仓库、架子、物品
计算机:数据库、集合、数据/文档
查看数据库
语法:show databases
效果:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x1dDi29I-1650722517388)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220413194132055.png)]
选择数据库 ! ! !
语法: use 数据库名
注意:选择不存在的数据库不会报错,后期当有数据时,系统会自动创建。隐式创建
查看集合
语法:show collections
创建集合
语法:db.creatCollection("集合名")
删除集合
语法:db.集合名.drop()
思考:如何删除数据库?
回答:1.通过use语法选择数据库
2.db.dropDatabases()
删除数据库
小总结
数据库(查看、创建、选择、删除)
查看 show databases
创建 有单独的语法,但是忽略,隐式创建
选择 use 数据库名
删除 1.通过use语法选择数据库 2.
db.dropDatabases()
删除数据库
集合(查看、创建、删除)
查看: show collections
创建:db.creatCollection(‘集合名’) 多学一招 忽略 后期插入数据 隐式创建集合
删除:db.集合名.drop()
MongoDB 文档增删改查(CURD)
明确需求
数据库主要用来存放项目数据
然后我们已经学会了数据库和集合的创建
思考:如何实现及合作数据的增删改查呢
回答: 通过MongoDB语法即可
C增
语法:db.集合名.insert(json数据)
说明:集合存在 则直接插入数据,集合不存在-隐式创建
练习:在test2 数据库的c1集合中插入数据(姓名叫webopenfather 年龄18岁)
use test2
db.c1.insert({uname:“webopenfather”,age:“18”})
留心1:数据库和集合不存在隐式创建
留心2:对象的键统一不加引号方便看,但是查看集合数据时系统会自动加
留心3:mongodb会给每条数据加一个全球唯一的_id键
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zwVwWaN3-1650722517390)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220413205347478.png)]
思考1:是否可以自定义_id值
回答:可以,只需要给插入的JSON数据增加_id键即可覆盖(但实战强烈不推荐)
db.c1.insert({_id:1})
思考2:如可插入多条记录?
回答:传递数组,数组中写一个个JSON数据即可
`db.c1.insert([` `{uname:'z3',age:3},` `{uname:'z4',age:4},` `{uname:'w5',age:5}` `])`
思考4:如何快速插入10条数据
回答:mongodb底层使用js引擎实现的,所以支持部分js语法
因此:可以写for循环
for(var i=1;i<=10;i++){
db.c2.insert({uname:“a”+i,age:i})
}
需求:在test2数据库c2集合中插入10条数据 分别为a1 a2 … a10
R查
基础语法 db.集合名.find(条件, [,查询的列])
条件
- 查询所有数据 {} 或者不写
- 查询age=6的数据 {age=6}
- 既要age=6又要性别=男 {age=6,sex=‘男’}
查询的列(可选参数)
- 不写 -这查询全部列(字段
- {age:1} 只显示age列(字段
- {age:0} 除了age列(字段都显示
留心:不管怎么写,系统自定义的_id都会在
升级语法
db.集合名.find({键:值}) 注:值不直接写
db.集合名.find({键:{运算符:值}})
运算符 | 作用 |
---|---|
$gt | 大于 |
$gte | 大于等于 |
$lt | 小于 |
$lte | 小于等于 |
$ne | 不等于 |
$in | in |
$nin | not in |
只获取 age为5,8,10 的数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RL2G7suL-1650722517390)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220413215703652.png)]
U改
基础语法 db.集合名.update(条件,新数据 [,是否新增,是否修改多条])
是否新增:指条件匹配不到数据则插入 true是 插入 false否 不插入默认
是否修改多条:指匹配成功的数据都修改 (true是,false否默认)
升级语法
db.集合名.update(条件,新数据 )
{修改器:{键:值}}
修改器 | 作用 |
---|---|
$inc | 递增 |
$rename | 重命名列 |
$set | 修改列值 |
$unset | 删除列 |
需求;是用修改器将zs4的姓名改为zs44
语法:
db.c3.update({uname:"zs4"},{$set:{uname:"zs44"}})
练习3:
db.c4.insert({uname:'神龙教主',age:888,who:'男',other:'非国人'})
完成需求:
uname 改成 神龙教主 {修改器:$set}
age 增加 111 {修改器:$inc}
who改字段 sex {修改器:$rename}
other 删除 {修改器:$unset}
语法分析:
db.c4.update({uname:'神龙教主'},{uname:"webopenfather"}) #错误 替换
{$set:{uname:"webopenfather"}}
{$inc:{age:111}}
{$rename:{who:"sex"}}
{$unset:{other:true}}
留心如何一次性写多个修改器
db.c4.update({uname:'神龙教主'},{
$set:{uname:"webopenfather"},
$inc:{age:111},
$rename:{who:"sex"},
$unset:{other:true}
})
D删
语法:db.集合名.remove(条件 [,是否删除一条])
作用:是否删除一条 true是 false 否 默认
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VKhL2ETu-1650722517391)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220414210322362.png)]
小总结
高级开发工程师简称:所有数据库都需要增删改查CURD
增Create
db.集合名.insert(JSON数据)
删Delete
db.集合名.remove(条件 [,是否删除一条 true是 false 否 默认])
也就是默认删除多条
改Update
db.集合名.update(条件 [,是否新增,是否修改多条])
升级语法db.update(条件,{修改器:{键:值}})
查
db.集合名.find(条件 [,查询的列])
练习
集合名称:学生集合
集合字段:编号、学号、姓名、电话、性别、年龄、学历、备注
代码:
use school
for(var num=1;num<=20;num++){
db.stu.insert({
id:num,
no:"QF"+num,
uname:"神龙教"+num,
tel:"1111111111",
sex:"女",
school:"研究生",
remark:"土豪"
})
}
MongoDB排序&分页
排序
- 语法:db.集合名.find().sort(JSON数据)
- 说明:键:就是要排序的列/字段、值:1 升序 -1 降序
- 练习 :年龄升序&降序
Limit与Skip方法
语法:db.集合名.find().sort().skip(数字).limit(数字)
说明:skip跳过指定数量(可选),limit限制查询的数量
实战分页
需求:数据库1~10条数据,每页显示两条(5页)
语法:db.集合名.find().skip().limit(2)
skip 计算公式:(当前页-1)*每页显示条数
1页 1 2 0
2页 3 4 2
3页 5 6 4
4页 7 8 6
5页 9 10 8
MongoDB聚合查询
明确需求
思考:如何统计数据、实现分组统计等?
回答:通过MongoDB聚合查询
概念
顾名思义就是把数据聚起来,然后统计
语法
语法
db.集合名称.aggregate([
{管道:{表达式}}
.....
])
常用管道
$group 将集合中的文档分组,用于统计结果
$match 过滤数据,只要输出符合条件的文档
$sort 聚合数据进一步排序
$skip 跳过指定文档数
$limit 限制集合数据返回文档数
.....
常用表达式
$sum 总和 $sum:1 同count表示统计
$avg 平均
$min 最小值
$max 最大值
....
准备
use test4
db.c1.insert({_id:1,name:"a",sex:1,age:1})
db.c1.insert({_id:2,name:"a",sex:1,age:2})
db.c1.insert({_id:3,name:"a",sex:2,age:3})
db.c1.insert({_id:4,name:"b",sex:2,age:4})
db.c1.insert({_id:5,name:"c",sex:2,age:5})
统计 | ||
---|---|---|
练习
-
统计男生、女生的总年龄
db.c1.aggregate([ { $group:{ _id:"$sex", rs:{$sum:"$age"} } } ..... ])
-
统计男生、女生的总人数
db.c1.aggregate([
{
$group:{
_id:"$sex",
rs:{$sum:1}
}
}
.....
])
- 求学生总数和平均年龄
db.c1.aggregate([
{
$group:{
_id:null,
total_num:{$sum:1},
total_avg:{$avg:"$avg"}
}
}
.....
])
查询男生、女生人数,按人数升序
db.c1.aggregate([
{
$group:{
_id:"$sex",
rs:{$sum:1}
},
$sort:{
rs:1
}
}
.....
])
MongoDB优化索引
数据库中的索引
- 说明:索引是一种排序好的便于查询的数据结构
- 作用:帮助数据库高效的查询
语法
-
创建索引语法:db.集合名.createIndex{待创建索引的列 [,额外选项]}
-
参数:
待创建索引的列:{键:1,...,键:-1} 说明:1升序 -1降序 例如{age:1}表示创建age索引并按照升序的方式存储 额外选项:设置索引的名称或者唯一索引等等
-
删除索引语法:
全部删除:db.集合名.dropIndexes() 删除指定:db.集合名.dropIndex(索引)
-
查看索引语法:db.集合名.getIndexes()
注意:自定义索引名字
语法:db.集合名.creatIndex({name:1},{name:“自定义的名字”})
创建唯一索引
语法:db.集合名.createIndex({待添加索引的列, {unique:列名})
分析索引
语法:db.集合名.find().explain(“executionStats”)
选择原则
为常作条件、排序、分组、联合操作的字段建立索引
选择唯一索引 (ps:同值较少如性别字段)
选择较小的数据列,为较长的数据列使用前缀索引 (ps:索引文件更少)
MongoDB权限机制
明确需求
发现我们在DOS中直接输入命令就可以登录数据库
这在实战中绝对不允许的
思考:如何解决
回答:使用权限机制,开启验证模式即可
语法
创建账号
db.createUser({
"user":"账号",
"pwd":"密码",
"roles":[{
role:"角色",
db:"所属数据库"
}]
})
角色
#角色种类
超级用户角色:root
数据库用户角色:read、readWrite
数据库管理角色:dbAdmin、userAdmin
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
备份恢复角色:backup、restore
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
开启验证服务
开启验证服务概念:名词,指用户需要输入账号密码才能登录使用
操作步骤
添加超级管理员
退出卸载服务
重新安装需要输入账号密码的服务(注在原安装命令基础上加上 --auth即可
启动服务 -> 登录测试
步骤1:添加超级管理员
mongo
use admin db.createUser({ "user":"admin", "pwd":"admin888", "roles":[{ role:"root", db:"admin" }] })
脚下留心:2x 3x 4x 前面版本看不到admin 没关系 直接选中
步骤2:卸载服务
bin\mongod --remove
注意:必须用管理员身份
步骤3:安装需要身份验证的MongoDB服务
bin\mongod --install --dbpath 存放目录 例如:E:\mongodb\data --logpath E:\mongodb\logs --auth
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHE0Hkca-1650722517392)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220416204812398.png)]
步骤4:登陆测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ODqaMsX0-1650722517393)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220416204929895.png)]
- 以前有警告 就是不安全
- 默认看不到数据库
通过超级管理员账号登录
- 方法1:mongo 服务器IP地址:端口/数据库 -u 用户名 -p密码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xg2BF3xq-1650722517394)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220416205722953.png)]
-
方法2:a-先登录,b-选择数据库 ,c-输入db.auth(用户名,密码)
添加用户并设置权限
use shop db.createUser({ "user":"shop1", "pwd":"admin888", "roles":[{ role:"read", db:"shop" }] }) db.createUser({ "user":"shop2", "pwd":"admin888", "roles":[{ role:"readWrite", db:"shop" }] })
MongoDB备份还原
明确需求
在实战中一定要做好数据库备份工作
否则万一数据丢失
带来的影响是巨大的
备份数据库mongodump
-
语法
导出数据语法:mongodump -h -prot -u -p -d -o 导出语法说明: -h host 服务器IP地址(一般不写 默认本机) -prot 端口(一般不写 默认27017) -u user 账号 -p pwd 密码 -d database 数据库(数据库不写则导出全部 -o open 备份到指定目录下
-
练习( 备份所有数据 ) mongodump -u admin -p admin888 -o D:\Download\mongodb\bak
-
练习(备份指定数据) mongodump -u shop1 -p admin888 -d shop -o D:\Download\mongodb\bak2
还原数据库mongorestore
-
语法
导出数据语法:mongorestore -h -prot -u -p -d --drop 导出语法说明: -h host 服务器IP地址(一般不写 默认本机) -prot 端口(一般不写 默认27017) -u user 账号 -p pwd 密码 -d 不写则还原全部数据 --drop 先删除数据库再导入 不写则覆盖
-
练习( 还原所有数据 ) mongorestore -u admin -p admin888 --drop D:\Download\mongodb\bak
-
练习(还原指定数据) mongorestore -u shop1 -p admin888 -d shop --drop D:\Download\mongodb\bak2\shop
实战可视化管理工具
安装Robo 3T
网址:Robo 3T | Free, open-source MongoDB GUI (formerly Robomongo)
之后傻瓜式安装,直接下一步下一步就好了
使用Robo 3T
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cdrI23WN-1650722517394)(C:\Users\tian123456\AppData\Roaming\Typora\typora-user-images\image-20220417110533669.png)]
mongoose
是什么
是node中提供操作MongoDB的模块
能干吗
能够通过node语法实现MngoDB数据库增删改查
从而实现用node写程序来管理MongoDB数据库
下载
npm i mongoose
或者
yarn add mongoose 更快
schema
中文网: http://mongoosejs.net/
作用:用来约束MongoDB文档数据(哪些字段必须,哪些字段可选的)
model
一个模型 对应一个集合
后面我们通过模型来管理集合中的数据
mongoose的使用
语法
//一、导入模块
const mongoose=require("mongoose")
//二、连接数据库
const db=mongoose.createConnection('mongodb://user:pass@localhost:port/database',
{useNewUrlParser:true,useUnifiedTopology:true},err=>{
if(err){
console.log('--------------------------------------------------')
console.log('数据库连接失败:',err)
console.log('--------------------------------------------------')
return;
}
console.log('数据库连接成功')
})
//三、设置数据模型(声明是哪个集合,限制字段个数和字段类型)
const model=db.model('user',{
name:{type:String,default:"username"},
age:{type:Number},
sex:{type:String}
})
// 四、创建实例操作(CURD)
// 增 -------------------------------
const insertObj=new model(数据对象)
方法1:insertObj.save((err)=>db.close())
方法2(推荐)
insertObj.save()
.then(res=>{
return res
})
.catch(err=>{
console.log('插入失败'+err)
return false
})
// 删 ---------------------------------------
方法1:model.remove/deleteOne/deleteMany(条件对象,(err)=>db.close())
方法2(推荐)
model deleteOne(条件对象)
.then(res=>{
return res.deletedCount
})
.catch(err=>{
console.log('删除失败'+err)
return false
})
//改 ---------------------------------------
方法1:model.update/updateOne/updateMany(条件对象,数据对象,(err)=>db.close())
方法2:(推荐)
model.updateOne(条件对象,数据对象)
.then(res=>{
return res.nModified
})
.catch(err=>{
console.log('修改失败'+err)
return false
})
//查 ----------------------------------------------
方法1:model.find/findOne(条件对象,要显示的字段数据对象,(err,result)=>db.close())
方法2:(推荐)
model.findOne(条件对象)
.then(res=>{
return res
})
.catch(err=>{
console.log(err)
return false
})
接口测试工具
postman
作用:模拟HTTP请求,测试接口,查看接口返回数据
官网:www.getpostman.com