七、MongoDb
7.1概念
MongoDb是一个基于分布式文件存储数据库,官网:www.mongodb.com
- 数据库(database):数据库是一个数据仓库,数据库服务下可以创建很多数据库,数据库中可以存放很多集合;
- 集合(collection):集合类似于 Js 中的数组,在集合中可以存放很多文档
- 文档(document):文档是数据库中的最小单位,类似于JS中的对象
7.2 docker环境安装mongodb
1)下载镜像
shell
docker pull mongodb/mongodb-community-server
2)启动容器并创建用户和密码
shell
docker run --name mongodb7.0.5 -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=password -d mongodb/mongodb-community-server
3)通过mongosh连接mongodb
shell
mongosh -u admin --host xx.xx.xx.xx
7.3Mongodb常用命令
shell
#数据库命令
show dbs #显示所有数据库
use <databaseName> #切换到指定数据库,如果数据库不存在,则会创建数据库
db #显示当前所在数据库
db.dropDatabase() #删除当前数据库
#集合命令
db.createCollection('<collectionName>') #创建集合
show collections #查看当前数据库下的所有集合
db.<collectionName>.renameCollection('<newName>') #集合重命名
#文档命令
db.<collectionName>.insert({'key1':'value','key2':'value2',...}) #插入文档
#插入文档后,会自动生成一个_id字段
db.<collectionName>.find(<查询条件>) #查询文档,如果没有查询条件,则列出所有文档
#修改文档(只修改第一个匹配到的文档)
db.<collectionName>.updateOne(<查询条件>,{$set:{key:value}})
#修改文档(修改所有匹配到的文档)
db.<collectionName>.updateMany(<查询条件>,{$set:{key:value}})
#删除文档(只删除第一个匹配到的文档)
db.<collectionName>.deleteOne(<查询条件>)
#修改文档(删除所有匹配到的文档)
db.<collectionName>.deleteMany(<查询条件>)
7.4 Mongoose
7.4.1 使用Mongoose连接数据库
1)安装mongoose
shell
npm i mongoose
2)连接代码
js
//1.引入mongoose
const mongoose=require('mongoose')
//2.连接数据库
mongoose.connect('mongodb://<host>:<port>/<databaseName>')
//3.设置回调
mongoose.connection.on('open',()=>{
console.log('连接成功')
})
mongoose.connection.on('error',()=>{
console.log('连接失败')
})
mongoose.connection.on('close',()=>{
console.log('连接关闭')
})
setTimeout(()=>{
//关闭连接
mongoose.disconnect()
},3000)
7.4.2字段类型
类型 | 描述 |
---|---|
String | 字符串 |
Number | 数字 |
Boolean | 布尔值 |
Array | 数组,也可以用[]表示 |
Date | 日期 |
Buffer | Buffer对象 |
Mixed | 任意类型,需要使用Mongoose.Schema.Type.Mixed指定 |
ObjectId | 对象ID,需要使用Mongoose.Schema.Type.ObjectId指定 |
Decimal128 | 高精度数字,,需要使用Mongoose.Schema.Type.Decimal128指定 |
7.4.3字段值验证
title:{
type:String,
required:true, //设置为必填项
default:'sally', //设置默认值
enum:['value1','value2',...], //设置枚举值,属性值必须在数组中有的
unique:true, //设置唯一值(必须重建集合才能生效)
}
7.4.4 新增文档
js
mongoose.connection.on('open',()=>{
console.log('连接成功')
//创建文档结构对象
//设置集合中文档的属性,及属性值的类型
let BookSchema=new mongoose.Schema({
name:String,
auther:String,
price:Number
})
//创建模型对象,对文档操作的封装对象,这个集合名如果写成英文单数,系统会自动变成复数
let Bookmodel=mongoose.model('books',BookSchema)
//新增文档
Bookmodel.create({
name:'三国演义',
auther:'ruguanzhon',
price:'400'
}).then((data)=>{
//如果插入成功,打印插入的数据并断开连接
console.log(data)
mongoose.disconnect()
}).catch((e)=>{
//如果插入失败,打印错误信息并断开连接
console.log(e)
mongoose.disconnect()
})
})
7.4.5删除文档
js
mongoose.connection.on('open',()=>{
console.log('连接成功')
//创建文档结构对象
//设置集合中文档的属性,及属性值的类型
let BookSchema=new mongoose.Schema({
name:String,
auther:String,
price:Number
})
//创建模型对象,对文档操作的封装对象,这个集合名如果写成英文单数,系统会自动变成复数
let Bookmodel=mongoose.model('books',BookSchema)
//删除匹配到的第一个文档
Bookmodel.deleteOne({
name:'三国演义',
}).then((data)=>{
//如果插入成功,打印插入的数据并断开连接
console.log(data)
}).catch((e)=>{
//如果插入失败,打印错误信息并断开连接
console.log(e)
})
//删除匹配到的所有文档
Bookmodel.deleteMany({
name:'三国演义',
}).then((data)=>{
//如果插入成功,打印插入的数据并断开连接
console.log(data)
mongoose.disconnect()
}).catch((e)=>{
//如果插入失败,打印错误信息并断开连接
console.log(e)
mongoose.disconnect()
})
})
7.4.6修改文档
js
//将name为三国演义的书,price修改为300
Bookmodel.updateOne(
//只修改匹配到的单个文档
{name: '三国演义'},
{price:300,}
).then((data)=>{
console.log(data)
mongoose.disconnect()
}).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
})
Bookmodel.updateMany(
//修改匹配到的所有文档
{name: '三国演义'},
{price:300,}
).then((data)=>{
console.log(data)
mongoose.disconnect()
}).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
})
mongoose.connection.on('error',()=>{
console.log('连接失败')
})
mongoose.connection.on('close',()=>{
console.log('连接关闭')
})
7.4.7读取文档
js
//读取匹配到的第一个文档
Bookmodel.findone(
{price: 200},
).then((data)=>{
console.log(data)
mongoose.disconnect()
}).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
})
//读取匹配到的所有文档
Bookmodel.find(
{price: 200},
).then((data)=>{
console.log(data)
mongoose.disconnect()
}).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
})
7.4.8条件控制
1)运算符
- $gt :大于
- $lt :小于
- $gte:大于等于
- $lte:小于等于
- $ne:不等于
示例:
js
//查找age大于40的所有文档
db.books.find({age:{$gt:40}})
2)逻辑运算符
js
{$or:[{条件1},{条件2}...]} //逻辑或
{$and:[{条件1},{条件2}...]} //逻辑与
示例:
js
//查找name为三国演义且价格为300的文档
Bookmodel.find(
{$and:[{name:'三国演义'},{price:'300'}]},
).then((data)=>{
console.log(data)
mongoose.disconnect()
}).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
3)正则表达式
js
{name:/三/} //匹配name属性值中包含'三'的文档
{name:new RegExp('三')} //效果同上
7.4.9个性化读取文档
1)筛选字段
js
//只获取name和price字段,不获取_id字段
Bookmodel.find().select({name:1,price:1,_id:0}).exec().then(
(data)=>{
console.log(data)
mongoose.disconnect()
}
).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
2)排序
js
//根据price降序排列({price:-1}代表降序,{price:1}代表升序)
Bookmodel.find().sort({price:-1}).exec().then(
(data)=>{
console.log(data)
mongoose.disconnect()
}
).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
3)数据截取
js
//skip(2).limit(3)代表先跳过匹配到的前两条数据,再载取接下来的3条数据,也就是截取第3到第5条数据
Bookmodel.find().sort({price:-1}).skip(2).limit(3).exec().then(
(data)=>{
console.log(data)
mongoose.disconnect()
}
).catch((e)=>{
console.log(e)
mongoose.disconnect()
})
7.4.10 mongoose代码模块化
js
//./db/config.js 用于存放数据库配置信息
module.exports={
userName:'username',
password:'password',
host:'host',
port:'prot',
database:'databasename',
authMechanism:'DEFAULT'
}
js
// ./db/db.js 封装数据库代码
//1.引入mongoose
const mongoose=require('mongoose')
//2.引入数据库配置文件
const config=require('./config')
//3.数据库连接函数
function db_connect(success,error){
//如果调用者没有传递error函数,则将error定义为一个默认函数
if (typeof(error)!=='function'){
error=()=>{
console.log('连接失败')
}
}
//连接数据库(数据库配置信息来源于config.js) mongoose.connect(`mongodb://${config.userName}:${config.password}@${config.host}:${config.port}/${config.database}?authMechanism=${config.authMechanism}&authSource=admin`)
mongoose.connection.on('open',()=>{
//连接成功则执行success()函数
success()
})
mongoose.connection.on('error',()=>{
//连接失败则执行error(函数)
error()
})
mongoose.connection.on('close',()=>{
console.log('连接关闭')
})
}
//定义数据库关闭函数
function db_close(){
mongoose.disconnect()
}
//将数据库连接函数和数据库关闭函数暴露出去
module.exports={
db_connect,
db_close
}
js
// ./db/bookModel.js 封装集合模型对象
//1.引入mongoose
const mongoose=require('mongoose')
//2.定义文档结构
let BookSchema=new mongoose.Schema({
name:String,
auther:String,
price:Number
})
//3.创建模型对象,对文档操作的封装对象,这个集合名如果写成英文单数,系统会自动变成复数
let Bookmodel=mongoose.model('books',BookSchema)
//4.暴露集合模型对象
module.exports=Bookmodel
js
// index.js
//引入封装好的数据库代码
const db=require('./db/db')
//引入封装好的集合模型对象
const BookModel=require('./db/bookModel')
//调用数据库连接函数
db.db_connect(()=>{
console.log('连接成功')
//调用集合模型对象来插入数据
BookModel.create({
name:"三体",
price:180
}).then((data)=>{
console.log(data)
db.db_close()
}).catch((e)=>{
console.log(e)
db.db_close()
})
})