文章目录
- 1. 介绍
- 2. mongoose 连接数据库
- 3. 插入文件
- 4. 字段类型
- 5. 字段值验证
- 6. 文档处理
- 6.1 删除文档
- 6.2 更新文档
- 6.3 读取文档
- 7. 条件控制
- 8. 个性化读取
- 9. 代码模块化
1. 介绍
Mongoose是一个对象文档模型库,官网http://www.mongoosejs.net/
方便使用代码操作mongodb数据库
mangoose 本身是一个包
上节内容Node.js – MongoDB
我们学习了在命令行手动交互,发命令请求,项目运行阶段明显是不可行的,但是我们可以借助mongoose
2. mongoose 连接数据库
- 创建一个文件夹,对其npm i -y 初始化
- 安装npm i mongoose
- 创建测试文件
- 导入mongoose
const mongoose = require(‘mongoose’)
- 连接 mongodb 服务
mongoose.connect(‘服务url’)
mongoose.connect(‘mongodb://127.0.0.1/test’)
其中端口号:27017 可写可不写 因为mongodb 的默认端口就是:27017 test 指的是数据库名称
- 设置回调
// 设置连接成功的回调
mongoose.connection.on(‘open’,()=>{
console.log(‘连接成功’)
})
// 设置连接失败的回调
mongoose.connection.on(‘error’,()=>{
console.log(‘连接失败’)
})
// 设置连接关闭的回调
mongoose.connection.on(‘close’,()=>{
console.log(‘连接关闭’)
})
// 关闭mongodb 的连接
setTimeOut(()=>{
mongoose.disconnect()
},2000)
补充说明
- 我们运行测试文件后可能会出现上图所示的警告,如果需要规避这个警告可以在文件中添加:
mongoose.set(‘strictQuery’,true)
- 设置连接成功的回调 once 只执行一次
mongodb.connection.once('open',()=>{
console.log('连接成功')
})
连接服务成功会执行回调函数,但是mongodb 服务如果意外掉线,on()会重新连接服务,once() 不会再连接服务;但是官方更推荐使用once() ,因为’open’ 事件中会写一些功能代码,重连服务会出现端口被占用的情况,导致某些代码无法运行。
这部分补充内容了解即可。
3. 插入文件
const mongoose = require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/test')
mongoose.connection.on('open', () => {
// 1. 创建文档的结构对象
// 设计集合中文档的属性以及属性值的类型
let UserSchema = new mongoose.Schema({
name: String,
birthYear: Number,
order:Number
})
// 2. 创建模型对象 对文档操作的封装对象
// 对文档的操作需要通过UserModel 进行
let UserModel = mongoose.model('users', UserSchema)
// 3. 新增
UserModel.create({
name: '王一珩',
birthYear: 2004,
order:10
}, (err, data) => {
if (err) {
console.log(err);
}
// 没有出错就输出插入后的文档对象
console.log(data);
// 关闭连接 但是项目运行阶段一般都不会关闭
mongoose.disconnect()
})
})
mongoose.connection.on('error', () => {
console.log('连接失败');
})
mongoose.connection.on('close', () => {
console.log('连接关闭');
})
// 设置服务在2s 后关闭
setTimeout(() => {
mongoose.disconnect()
}, 2000)
4. 字段类型
文档结构可选的常用字段类型列表
字段类型也可以说是指文档对象的属性值类型
类型 | 描述 |
---|---|
String | 字符串 |
Number | 数字 |
Boolean | 布尔值 |
Array | 数组,也可以使用[ ]来标识 |
Date | 日期 |
Buffer | Buffer对象 |
Mixed | 任意类型,需要使用mongoose.Schema.Types.Mixed 指定 |
Objected | 对象ID,需要使用mongoose.Schema.Types.Objected |
Decimal128 | 高精度数字,需要使用mongoose.Schema.Types.Decimal128 |
存储视频、图片一般都是存储在静态资源文件夹下,把相应的url 以字符串的形式存储在数据库中,使用的时候就按照url 到数据库中寻找;
Objected :一般用来做外键,就是将一个文档的ID存储到另一个文档中,当需要这个文档的数据是就通过ID 进行数据查询;
5. 字段值验证
mongoose 有一些内建验证器,可以对字段值进行验证
- 必填项
title:{
type:String,
required:true}
- 默认值
author:{
type: String,
default: ‘匿名’
} // 设置文档对象没有传入author值,那author 值默认就为 匿名
- 枚举值
gender:{
type:String,
enum:[‘男’,‘女’]
} // 设置的值必须是数组中的
- 唯一值
username:{
type:String,
unique: true
}
unique 需要重建集合
才有效,也就是创建新的集合
6. 文档处理
6.1 删除文档
- 删除单条数据
// 创建模型对象对文档操作的封装对象 mongoose会使用集合名称的复数,创建集合
let BookModel = mongoose.model('novel',BookSchema);
// 集合名称就为novels
// 删除一条
BookModel.deleteOne({_id:'63f34af50cf203761ede1892'},(err,data)=>{
//判断
if(err){
console.log('删除失败');
return;
}
//输出data
console.log(data);
- 批量删除
BookModel.deleteMany({is_hot:false},(err,data)=>{
//判断
if(err){
console.1og('删除失败');
return;
}
//输出data
console.log(data);
})
6.2 更新文档
- 更新一条
BookModel.updateOne({name:'红楼梦'},{price:9.9},(err,data)=>{
//判断 err
if (err) {
console.log('更新失败')
return
}
// 输出data
console.log(data);
- 批量更新
//批量更新
BookModel.updateMany({author:''},{is_hot:true},(err,data)=>{
//判断
if(err){
console.log('更新失败');
return;
}
//输出data
console.log(data);
})
6.3 读取文档
- 读取一条
BookModel.findOne({name:'红楼梦'},(err,data)=>{
//判断 err
if (err) {
console.log('读取失败')
return
}
// 输出data
console.log(data);
// 也可以使用根据ID 获取数据 findById()
BookModel.findById({id:'12345678790'},(err,data)=>{
//判断 err
if (err) {
console.log('读取失败')
return
}
// 输出data
console.log(data);
- 批量读取
BookModel.find({author:''},(err,data)=>{
//判断
if(err){
console.log('读取失败');
return;
}
//输出data
console.log(data);
- 读取所有
BookModel.find((err,data)=>{
//判断
if(err){
console.log('读取失败');
return;
}
//输出data
console.log(data);
})
7. 条件控制
- 运算符
本节内容的代码中我们都是通过 ‘=’ 进行检索内容,但是其他的运算符也可以进行检索内容。
在mongodb不能><>=<=!=等运算符,需要使用替代符号
- ‘>’ 使用
$ gt
- ‘<’ 使用
$ lt
- ‘>=’ 使用
$ gte
- ‘<=’ 使用
$ lte
- ‘!==’ 使用
$ ne
db.students.find({id: {$ gt: 3}) id号比3大的所有记录
let BookModel = mongoose.model('novel',BookSchema);
// 价格<20的图书
BookModel.find({price:{$lt:20}},(err,data)=>{
if(err)
console.log('读取失败');
return;
console.log(data);
})
- 逻辑运算
$or
逻辑或的情况
db.students.find({$or [{age:18},{age:24}]))
$and
逻辑与的情况
db.students.find({$ and: [{age:{$ lt:20}},{age: {$gt:15}}]});
- 正则匹配
条件中可以直接使用JS的正则语法,通过正则可以进行模糊查询
db.students.find({name: /imissyou/ }) // 找出name 中含有imissyou 的文档对象
8. 个性化读取
- 字段筛选
// 0:不要的字段
// 1:要的字段
SongModel.find().select({_id:0,title:1}).exec(function(err,data)=>{
if(err){
console.log(err)
}
console.log('data')
mongoose.connection.close()
})
- 数据排序
// sort 排序
// 1:升序
// -1:倒序
SongModel.find().select({_id:0,price:1}).sort({price:-1}).exec(function(err,data)=>{
if(err){
console.log(err)
}
console.log('data')
mongoose.connection.close()
})
- 数据截取
// 取前三个
SongModel.find().select({_id:0,price:1}).sort({price:-1}).limit(3).exec(function(err,data)=>{
if(err){
console.log(err)
}
console.log('data')
mongoose.connection.close()
})
// 取第4-6位
SongModel.find()
.select({_id:0,price:1})
.sort({price:-1})
.skip(3)
.limit(3)
.exec(function(err,data)=>{
if(err){
console.log(err)
}
console.log('data')
mongoose.connection.close()
})
9. 代码模块化
- 创建连接部分
-
新建文件夹db 接着新建文件db ,再其中把创建连接代码部分放入暴露的函数中
注意:
连接成功泽调用success 函数,连接失败调用error函数 -
导入函数,调用函数,传入success、error函数
- 创建结构对象和模型对象部分
-
创建modules 文件夹 再创建BookModel.js ,放入重复创建的代码部分;
-
只需要在文件中导入两部分模板内容,传入函数的success和error 参数
- 模板化调用函数的error参数部分
- 不再传入error参数
- 判断error 是否为函数
- 配置文件
连接的url、端口号、集合都有可能发生改变,所以我们可以把其中内容写入到配置文件中,将来再修改的时候也更加方便;
- 创建config 文件夹 ,在创建config 文件,放入url、端口号、集合等内容