Mongoose (快速入门)
mongoose 学习
mongoose 基础
介绍
- Mongoose 是一个让我们可以通过Node来操作MongoDB数据库的一个模块
- Mongoose 是一个对象文档模型(ODM)库,它是对Node原生的MongoDB模块进行了进一步的优化封装
- 大多数情况下,他被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型装换等好处
- 基于MongoDB驱动,通过关系型数据库的思想来实现非关系型数据库
优势/好处
- 为文档创建模式结构(Schema),也可以说是约束
- 对模型中的对象/文档进行验证
- 数据可以通过类型装换装换为对象模型
- 可以使用中间件来应用业务逻辑挂钩
- 相比MongoDB驱动更容易
new Object
Schema(模式对象)
——Schema 对象定义约束了数据库中的文档结构
Model
——Model 对象作为集合中的所有文档的表示,相当于MongoDB中的collection,它的每一个实例就是一个document文档
Document
——Document表示集合中的具体文档,相当于collection中的一个具体文档
关系:Schema生成Model,Model创造Document
简单使用
前提:安装MongoDB,Nodejs
下载安装Mongoose
npm i mongoose --save
项目中引入mongoose
var mongoose = require(‘mongoose’)
连接MongoDB数据库
mongoose.connect(‘mongodb://数据库ip地址 : 端口号( 默认端口27017可以省略 )/数据库名’)
数据库连接状态
connect()返回的是一个待定状态,在mongoose中有一个属性叫 connection 用来表示数据库的连接
通过监视该对象可以用来监听数据库的连接与断开
数据库连接成功事件
mongoose.connection.once(‘open’ , () => {})
数据库断开事件
mongoose.connection.once(‘close’ , () => {})
创建Schema(模式)对象
var stuSchema = new Schema({})
- 通过
Schema
创建Model
- Model 代表的是数据库中的集合,通过Model才能对数据库进行操作
- 通过
映射
var stuModel = mongoose.model(‘student’,stuSchema)
参数
要映射的集合名
创建的约束(Schema对象)
通过映射返回的值对数据库进行增、删、改、查
断开数据库连接(一般不使用)
mongoose.disconnect()
使用案例
var mongoose = require('mongoose')
var Schema = mongoose.Schema;
//连接数据库
mongoose.connect('mongodb://localhost:27017/student',{useNewUrlParser: true
})//监听数据库连接状态
mongoose.connection.once('open',()=>{console.log('数据库连接成功……')
})
mongoose.connection.once('close',()=>{console.log('数据库断开……')
})//创建Schema对象(约束)
var stuSchema = new Schema({name: String,age: Number,gender:{type: String,default:'male'},addr: String
})//将stuSchema映射到一个MongoDB collection并定义这个文档的构成
var stuModle = mongoose.model('student',stuSchema)//向student数据库中插入数据
stuModle.create({name:"小明",age:"20",addr:"天津"
},(err,docs)=>{if(!err){console.log('插入成功'+docs)}
})
/*
* 控制台结果:
* 数据库连接成功……
* 插入成功{
* gender: 'male',
* _id: 6017a189372ece49089d79c7,
* name: '小明',
* age: 20,
* addr: '天津',
* __v: 0
* }
*/
/*
* 数据库结果:
* | _id | gender | name | age | addr | __v |
* | ------------------------ | ------ | ---- | ---- | ---- | ---- |
* | 6017a189372ece49089d79c7 | male | 小明 | 20 | 天津 | 0 |
*/
模式(Schemas)
每个 schema 都会映射到一个 MongoDB collection 并定义这个collection里的文档结构
支持的字段类型
类型 作用 String 定义字符串 Number 定义数字 Date 定义日期 Buffer 定义二进制 Boolean 定义布尔值 Mixed 定义混合类型 ObjectId 定义对象ID Array 定义数组 创建一个 schema 对象
const mongoose = require('mongoose') //调用 Schema const Scheme = mongoose.Schema//创建 schema 对象 var stuSchema = new Schema({name: String,age: Number,gender:{type: String,default:'male' //定义默认类型},addr: String })
在Schema定以后添加字段时需要使用 add() 方法
var schema = new Schema() schema.add({stuId:Number,})
【timestamps】
——当 schema 中设置timestamps为 true 时,schema映射的文档 document 会自动添加 createdAt 和 updatedA t这两个字段,代表创建时间和更新时间
var stuSchema = new Schema({{...},{ timestamps:true } })
【_id】
——当未定义
_id
字段时 mongoose 会为每一个文档自动添加一个不重复的_id
,类型为ObiectId(在查询语句中需要通过 findById() 才能查询)
文档新增
【save()】
操作的是文档
Model.prototype.save([options], [options.safe], [options.validateBeforeSave], [fn])
案例:
var mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',(err) => {if(!err){var schema = new mongoose.Schema({name:String,grades:Number})var stuModel = mongoose.model('grades',schema)//链式调用 通过new 一个Model创建一个 documentnew stuModel({name:"小明",grades:68}).save((err,docs) => {if(!err){console.log(docs)//{ _id: 6017bd1cf4cc8544d8ed2a8a, name: '小明', grades: 68, __v: 0 }}})} })
【create()】
操作模型
Model.create(doc(s), [callback])
参数:
[doc(s)]:文档对象或文档对象数组
[callback]:回调函数
案例:
var mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',(err) => {if(!err){var schema = new mongoose.Schema({name:String,grades:Number})var stuModel = mongoose.model('grades',schema)//链式调用 通过new 一个Model创建一个 documentstuModel.create({name:"小明",grades:68},{name:"小红",grades:80},(err,doc1,doc2) => {if(!err){console.log(doc1)//{ _id: 6017be2d77c8dd01242624bb, name: '小明', grades: 68, __v: 0 }console.log(doc2)//{ _id: 6017be2d77c8dd01242624bc, name: '小红', grades: 80, __v: 0 }}})} })
【insertMany()】
Model.insertMany(doc(s), [options], [callback])
返回值为一个数组
案例:
var mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',(err) => {if(!err){var schema = new mongoose.Schema({name:String,grades:Number})var stuModel = mongoose.model('grades',schema)//链式调用 通过new 一个Model创建一个 documentstuModel.insertMany({name:"小明",grades:68},{name:"小芳",grades:94},(err,docs) => {if(!err){console.log(docs)/*[{ _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 },{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }]*/}})} })
文档查询
数据表
_id name grades __v 6017befb5c36d64d08b72576 小明 68 0 6017befb5c36d64d08b72577 小芳 94 0 6017c455ba09d355a49ec8eb 小红 52 0 6017c455ba09d355a49ec8ec 小刚 46 0
【find()】
Model.find(conditions, [projection], [options], [callback])
参数
conditions:查询条件
[projection]:控制返回字段
[options]:配置查询参数
[callback]:回调函数–function(err,docs){}
案例:
var mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',(err) => {if(!err){var schema = new mongoose.Schema({name:String,grades:Number})var stuModel = mongoose.model('grades',schema)//查询所有数据stuModel.find((err,docs) => {if(!err){console.log(docs)}}) /* [{ _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 },{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 },{ _id: 6017c455ba09d355a49ec8eb, name: '小红', grades: 52, __v: 0 },{ _id: 6017c455ba09d355a49ec8ec, name: '小刚', grades: 46, __v: 0 }]*///查询成绩大于60以上的数据stuModel.find({grades:{$gte:60}},(err,docs) => {if(!err){console.log(docs)}})/*[{ _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 },{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }]*///查询成绩大于60以上且名字里存在‘芳’的数据stuModel.find({name:/芳/,grades:{$gte:60}},(err,docs) => {if(!err){console.log(docs)}})/*[* { _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }* ]*///查询名字里存在‘明’的数据且只输出‘name’字段//_id默认会返回stuModel.find({name:/明/},{name:1,_id:0},(err,docs) => {if(!err){console.log(docs)}})// [{name: '小明'}]//找出跳过前两条数据的其他数据stuModel.find(null,null,{skip:2},(err,docs) => {if(!err){console.log(docs)}})/*[{ _id: 6017c455ba09d355a49ec8eb, name: '小红', grades: 52, __v: 0 },{ _id: 6017c455ba09d355a49ec8ec, name: '小刚', grades: 46, __v: 0 }]*/} })
【findById()】
Model.findById(id, [projection], [options], [callback])
案例:
var mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',(err) => {if(!err){var schema = new mongoose.Schema({name:String,grades:Number})var stuModel = mongoose.model('grades',schema)//保存查询数据的_idvar aIDArr = []//查询所有数据stuModel.find((err,docs) => {if(!err){docs.forEach((item,index,arr)=>{aIDArr.push(item._id)})//显示第 0 个元素的所有字段stuModel.findById(aIDArr[0],(err,doc)=>{if(!err){console.log(doc)}})// { _id: 6017befb5c36d64d08b72576, name: '小明', grades: 68, __v: 0 }//显示第 0 个元素且只输出name字段stuModel.findById(aIDArr[0],{name:1,_id:0},(err,doc)=>{if(!err){console.log(doc)}})// { name: '小明' }//显示第 0 个元素且输出最少的字段(_id默认输出)stuModel.findById(aIDArr[0],{lean:true},(err,doc)=>{if(!err){console.log(doc)}})// { _id: 6017befb5c36d64d08b72576 }}})} })
【findOne()】
返回查询到的数据的第一个
Model.findOne([conditions], [projection], [options], [callback])
案例:
var mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',(err) => {if(!err){var schema = new mongoose.Schema({name:String,grades:Number})var stuModel = mongoose.model('grades',schema)//找出age>20的文档中的第一个文档stuModel.findOne({grades:{$gt:80}},(err,doc) => {if(!err){console.log(doc)}})//{ _id: 6017befb5c36d64d08b72577, name: '小芳', grades: 94, __v: 0 }//找出age>20的文档中的第一个文档,且只输出name字段stuModel.findOne({grades:{$gt:80}},{name:1,_id:0},(err,doc) => {if(!err){console.log(doc)}})//{ name: '小芳' }//找出age>20的文档中的第一个文档,且输出包含name字段在内的最短字段stuModel.findOne({grades:{$gt:80}},{lern:true},(err,doc) => {if(!err){console.log(doc)}})//{ _id: 6017befb5c36d64d08b72577 }} })
复杂查询【$where】
$where 可以使用任意的 JavaScript 作为查询的一部分,包含JavaScript 表达式的字符串或者函数
案例
var mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',(err) => {if(!err){var schema = new mongoose.Schema({name:String,grades:Number})//添加一个测试字段// schema.add({test:Number})var stuModel = mongoose.model('grades',schema)//添加两条数据// stuModel.create([{name:"小花",grades:76,test:76},{name:"小兰",grades:60,test:30}],(err,docs)=>{// console.log(docs)// })//字符串 es5中this与obj指向一样,es6中只能用objstuModel.find({$where:"this.grades == this.test" || "obj.grades == obj.test"},(err,doc) => {if(!err){console.log(doc)}})//[{_id: 6017d7cb8a95cb2a00aae3ae,name: '小花',grades: 76,test: 76,__v: 0}]//函数stuModel.find({$where:function() {return this.grades == this.test || obj.grades == obj.test*2}},(err,doc) => {if(!err){console.log(doc)}})/*[{_id: 6017d7cb8a95cb2a00aae3ae,name: '小花',grades: 76,test: 76,__v: 0},{_id: 6017d7cb8a95cb2a00aae3af,name: '小兰',grades: 60,test: 30,__v: 0}]*/} })
常用查询条件
$or 或关系
$nor 或关系取反
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
$in 在多个值范围内
$nin 不在多个值范围内
$all 匹配数组中多个值
$regex 正则,用于模糊查询
$size 匹配数组大小
$maxDistance 范围查询,距离(基于LBS)
$mod 取模运算
$near 邻域查询,查询附近的位置(基于LBS)
$exists 字段是否存在
$elemMatch 匹配内数组内的元素
$within 范围查询(基于LBS)
$box 范围查询,矩形范围(基于LBS)
$center 范围醒询,圆形范围(基于LBS)
$centerSphere 范围查询,球形范围(基于LBS)
$slice 查询字段集合中的元素(比如从第几个之后,第N到第M个元素
特定类型查询
数据表
_id name grades __v test 6017befb5c36d64d08b72576 小明 68 0 1 6017befb5c36d64d08b72577 小芳 94 0 3 6017c455ba09d355a49ec8eb 小红 52 0 5 6017c455ba09d355a49ec8ec 小刚 46 0 2 6017d7cb8a95cb2a00aae3ae 小花 76 0 4 6017d7cb8a95cb2a00aae3af 小兰 60 0 6
方法
方法 | 作用 |
---|---|
sort | 排序 |
skip | 跳过 |
limit | 限制 |
select | 显示字段 |
exect | 执行 |
count | 计数 |
distinct | 去重 |
案例:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
var stuModel = mongoose.model('grades', Schema);// 按test从小到大排序
stuModel.find().sort('test').exec((err,docs)=>{console.log(docs)
})
// 按test从大到小排列
stuModel.find().sort('-test').exec((err,docs)=>{console.log(docs)
})
// 跳过1个,显示其他
stuModel.find().skip(1).exec((err,docs)=>{console.log(docs)
})
// 显示2个
stuModel.find().limit(2).exec((err,docs)=>{console.log(docs)
})
// 显示name、grades字段,不显示_id字段
stuModel.find().select('name grades -_id').exec((err,docs)=>{console.log(docs)
})
// 跳过第1个后,只显示2个数据,按照grades由大到小排序,且不显示_id字段
stuModel.find().skip(1).limit(2).sort('-grades').select('-_id').exec((err,docs)=>{console.log(docs)/*[{ name: '小明', grades: 78, __v: 0, test: 1 },{ name: '小花', grades: 76, test: 4, __v: 0 }]*/
})
// 显示集合stuModel中的文档数量
stuModel.find().count((err,count)=>{console.log(count)//6
})
// 返回集合stuModel中的grades的值
stuModel.find().distinct('grades',(err,distinct)=>{console.log(distinct)//[ 46, 52, 60, 76, 78, 94 ]
})
文档更新
【update()】
Model.update(conditions, doc, [options], [callback])
参数
conditions:查询条件
doc:需要修改的数据(插入的数据)
[options]:控制选项
safe (boolean): 默认为true。安全模式。
upsert (boolean): 默认为false。如果不存在则创建新记录。
multi (boolean): 默认为false。是否更新多个查询记录。
runValidators: 如果值为true,执行Validation验证。
setDefaultsOnInsert: 如果upsert选项为true,在新建时插入文档定义的默认值。
strict (boolean): 以strict模式进行更新。
overwrite (boolean): 默认为false。禁用update-only模式,允许覆盖记录。[callback]:回调函数
若设置了查询条件,当数据库不满足时默认什么也不发生
update() 方法中的回调函数不能省略,否则数据不会更新,当回调无有用信息时可以使用exec()简化
stuModel.update({name:'小明'},{$set:{test:34}}.exec())
案例
//第一步,引入mongoose const mongoose = require('mongoose') //第二步,连接数据库 mongoose.connect('mongodb://localhost:27017/student',err=>{if(!err){//第三步,创建模板var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})// var Schema = new Schema()//第四步,将模板映射到集合并创建var stuModel = mongoose.model('grades',Schema)//查询name为小明的数据,并将其test更改为34//若有多个文档,默认只更新第一个stuModel.update({name:'小明'},{$set:{test:34}},(err,raw)=>{console.log(raw)})//{ n: 1, nModified: 1, ok: 1 }//6017befb5c36d64d08b72576 小明 68 0 34} })
【updateOne()】
- Model.updateOne(conditions, doc, [options], [callback])
- 与update()相似,唯一区别为updateOne() 默认更新一个文档,即使设置{multi:true}也无法只更新一个文档
【updateMany()】
Model.updateMany(conditions, doc, [options], [callback])
与update()相似,唯一区别为updateMany() 默认更新多个文档,即使设置{multi:false}也无法只更新一个文档
【find()+save()】
用于复杂更新
const mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',err=>{if(!err){var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel = mongoose.model('grades',Schema)//查询成绩小于60的数据,并在其名字后添加‘:差生’字段stuModel.find({grades:{$lt:60}},(err,docs)=>{console.log(docs);/*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: '小红',grades: 52,__v: 0},{test: 0,_id: 6017c455ba09d355a49ec8ec,name: '小刚',grades: 46,__v: 0}]*/docs.forEach((item,index,arr) => {item.name += ':差生'//将修改后的数据保存item.save()})console.log(docs)/*[{test: 0,_id: 6017c455ba09d355a49ec8eb,name: '小红:差生',grades: 52,__v: 0},{test: 0,_id: 6017c455ba09d355a49ec8ec,name: '小刚:差生',grades: 46,__v: 0}]*/})} })
【findOne() + save()】
用于复杂更新
findOne()返回值为文档对象
const mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',err=>{if(!err){var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel = mongoose.model('grades',Schema)//查询成绩小于60的数据,并在其名字后添加‘:差生’字段stuModel.findOne({name:'小明'},(err,doc)=>{console.log(doc);//[{test: 34,_id: 6017c455ba09d355a49ec8eb,name: '小明',grades: 68,__v: 0},doc.age += 10doc.save()console.log(docs)//[{test: 34,_id: 6017c455ba09d355a49ec8eb,name: '小明',grades: 78,__v: 0}})} })
【fingOneAndUpdate()】
- Model.findOneAndUpdate([conditions], [update], [options], [callback])
【findByIdAndUpdate()】
- Model.findByIdAndUpdate([conditions], [update], [options], [callback])
文档删除
【remove()】
会删除符合条件的所有数据
Model的remove()
const mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',err=>{if(!err){var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel = mongoose.model('grades',Schema)//删除名字中包含‘差生’的数据stuModel.remove({name:/差生/},function(err){})// 回调函数不能省略,但可以使用exec() 简写//stuModel.remove({name:/差生/}).exec()})} })
文档的remove()
const mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/student',err=>{if(!err){var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})var stuModel = mongoose.model('grades',Schema)//删除名字中包含‘差生’的数据stuModel.find({name:/差生/},function(err,docs){docs.forEach((item,index,arr)=>{item.remove((err,doc)=>{//doc为被删除的值console.log(doc)})})})})} })
【findOneAndRemove()】
删除符合条件的一条数据
Model.findOneAndRemove(conditions, [options], [callback])
回调不可省略,但可以使用exec() 简写
stuModel.findOneAndRemove({name:/差生/}).exec()
【findByIdAndRemove()】
- 通过id删除数据(id是唯一的)
- Model.findByIdAndRemove(conditions, [options], [callback])
- 回调不可省略,但可以使用exec() 简写
前后钩子
前后钩子即 pre() 和 post() 方法(中间件)
中间件在schema上指定,类似静态方法或实例方法等
可以在执行以下操作时设置前后钩子
init
validate
save
remove
count
find
findOne
findOneAndRemove
findOneAndUpdate
insertMany
update【pre()】:在执行某些操作前执行
【post】:在执行某些操作前后执行,不可以使用next()
案例:
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({ name:String,grades:Number,test:{type:Number,default:0}})
Schema.pre('find',function(next){console.log('我是pre方法1');next();
});
Schema.pre('find',function(next){console.log('我是pre方法2');next();
});
Schema.post('find',function(docs){console.log('我是post方法1');
});
Schema.post('find',function(docs){console.log('我是post方法2');
});
var stuModel = mongoose.model('grades', Schema);
stuModel.find(function(err,docs){console.log(docs[0]);
})
/*
我是pre方法1
我是pre方法2
我是post方法1
我是post方法2
{test: 34, _id: 6017befb5c36d64d08b72576,name: '小明',grades: 78,__v: 0}
*/
文档验证
- 保证保存文档时,可以按照Schema设置的字段进行设置
【required】:数据必填
//将name设置为必填字段,如果没有name字段,文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({name:{type:String,required:true},age:Number
})
var stuModel = mongoose.model('students', Schema);
new stuModel({age:20}).save((err,doc)=>{if(err){return console.log(err)}console.log(doc)
})//报错:name: Path `name` is required.
【default】:默认值
//设置age字段的默认值为18,如果不设置age字段,则会取默认值
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({name:String,age:{type:Number,default:18}
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'李雷'}).save((err,doc)=>{if(err){return console.log(err)}console.log(doc)
})//{ age: 18, _id: 6018f3bd7e51343e6c4f212b, name: '李雷', __v: 0 }
【min】【max】:最小/大值
- 只适用于数字
//将age的取值范围设置为[0,10]。如果age取值为20,文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({name:String,age:{type:Number,min:10,max:18}
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'李雷',age:20}).save((err,doc)=>{if(err){return console.log(err)}console.log(doc)
})//age: Path `age` (20) is more than maximum allowed value (18).
【match】:正则匹配
- 只适用于字符串
//将name的match设置为必须存在'01'字符。如果name不存在'01',文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({name:{type:String,match:/01/},age:Number,
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'李雷',age:20}).save((err,doc)=>{if(err){return console.log(err)}console.log(doc)
})//name: Path `name` is invalid (李雷).
【enum】:枚举匹配
- 只适用于字符串
//将name的枚举取值设置为['zs','ls','ww'],如果name不在枚举范围内取值,文档将不被保存,且出现错误提示
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({name:{type:String,enum:['zs','ls','ww']},age:Number,
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'lss',age:20}).save((err,doc)=>{if(err){return console.log(err)}console.log(doc)
})//name: ValidatorError: `lss` is not a valid enum value for path `name`.
【validate】:自定义匹配
- validate实际上是一个函数,函数的参数代表当前字段,返回true表示通过验证,返回false表示未通过验证
//定义名字name的长度必须在4个字符以上
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({name:{type:String,validate:nameLength},age:Number,
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'abcd',age:20}).save((err,doc)=>{if(err){return console.log(err)}console.log(doc)
})function nameLength(arg){if(arg.length>4){return true}return false
}//name: Validator failed for path `name` with value `abcd`
联表操作
localhost:27017/student’)
var Schema =new mongoose.Schema({
name:{type:String,enum:[‘zs’,‘ls’,‘ww’]},
age:Number,
})
var stuModel = mongoose.model(‘students’, Schema);
new stuModel({name:‘lss’,age:20}).save((err,doc)=>{
if(err){
return console.log(err)
}
console.log(doc)
})
//name: ValidatorError: lss
is not a valid enum value for path name
.
### 【validate】:自定义匹配* validate实际上是一个函数,函数的参数代表当前字段,返回true表示通过验证,返回false表示未通过验证```javascript
//定义名字name的长度必须在4个字符以上
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/student')
var Schema =new mongoose.Schema({name:{type:String,validate:nameLength},age:Number,
})
var stuModel = mongoose.model('students', Schema);
new stuModel({name:'abcd',age:20}).save((err,doc)=>{if(err){return console.log(err)}console.log(doc)
})function nameLength(arg){if(arg.length>4){return true}return false
}//name: Validator failed for path `name` with value `abcd`
联表操作
Mongoose (快速入门)相关推荐
- Mongoose快速入门
2019独角兽企业重金招聘Python工程师标准>>> Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model : 由Schema发布生成的模型,具 ...
- Shiro第一个程序:官方快速入门程序Qucickstart详解教程
目录 一.下载解压 二.第一个Shiro程序 1. 导入依赖 2. 配置shiro配置文件 3. Quickstart.java 4. 启动测试 三.shiro.ini分析 四.Quickstart. ...
- 计算机入门新人必学,异世修真人怎么玩?新手快速入门必备技巧
异世修真人怎么快速入门?最近新出来的一款文字修仙游戏,很多萌新不知道怎么玩?进小编给大家带来了游戏新手快速入门技巧攻略,希望可以帮到大家. 新手快速入门攻略 1.开局出来往下找婆婆,交互给点钱,旁边有 ...
- Spring Boot 2 快速教程:WebFlux 快速入门(二)
2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘 ...
- Apache Hive 快速入门 (CentOS 7.3 + Hadoop-2.8 + Hive-2.1.1)
2019独角兽企业重金招聘Python工程师标准>>> 本文节选自<Netkiller Database 手札> 第 63 章 Apache Hive 目录 63.1. ...
- 《iOS9开发快速入门》——导读
本节书摘来自异步社区<iOS9开发快速入门>一书中的目录,作者 刘丽霞 , 邱晓华,更多章节内容可以访问云栖社区"异步社区"公众号查看 目 录 前 言 第1章 iOS ...
- BIML 101 - ETL数据清洗 系列 - BIML 快速入门教程 - 序
BIML 101 - BIML 快速入门教程 做大数据的项目,最花时间的就是数据清洗. 没有一个相对可靠的数据,数据分析就是无木之舟,无水之源. 如果你已经进了ETL这个坑,而且预算有限,并且有大量的 ...
- python scrapy菜鸟教程_scrapy学习笔记(一)快速入门
安装Scrapy Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv.json等文件中. 首先我们安装Scrapy. pip install sc ...
- OpenStack快速入门
OpenStack云计算快速入门(1) 该教程基于Ubuntu12.04版,它将帮助读者建立起一份OpenStack最小化安装.我是五岳之巅,翻译中多采用意译法,所以个别词与原版有出入,请大家谅解.我 ...
- Expression Blend实例中文教程(2) - 界面快速入门
上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习. 在开始使用Ble ...
最新文章
- java udp tcp协议_【java】TCP和UDP传输协议
- 重载函数与函数模板(转)
- C# NameValueCollection集合 (转)
- 使用jquery制作计算器_如何使用jQuery对计算器进行编程
- [转]Android应用的自动更新
- Python 源码剖析(二)—— 第一次修改 Python 源代码
- open_cursors参数设置调优
- 新潮科技:人工智能歌词创作软件app,在线ai作词押韵写歌词,可以自己写歌词的软件
- 欧瑞变频器800参数设置_(完整版)ACS800变频器参数设定
- php里无法找到该网页,thinkphp搭建网站后端,入口文件找不到(无法加载)
- html图片橡皮擦特效,原生制作的js涂鸦画板特效 可调画笔颜色|粗细|橡皮檫功
- method call expected
- 关于RedisPool配置参数
- unity3d:win32api,托盘运行,开机自启动,浏览文件对话框,无标题栏,自定义标题栏拖动
- CentOS7 开启 BBR 加速
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十四) Be careful!前方怪物出没
- java毕业设计——基于java+Servlet+jsp的网上花店销售系统设计与实现(毕业论文+程序源码)——网上花店销售系统
- AD中出现off grid pin问题的解决方法
- 洛谷P5266 学籍管理
- python爬取身份证信息、爬取ip代理池
热门文章
- 抖音、微信关闭个性化推荐功能上线,用户真能摆脱“算法牢笼”吗?
- mrtg监控linux主机的甚至,windows上mrtg监控linuxcpu 内存
- 查询网站服务器存放地址,服务器存放地址查询
- Google Talk可以使用了(我的试用手记)
- H.264的DTS、PTS、frame_num、poc
- 翻斗式雨量计(脉冲型)是如何计算出降雨量的?
- excel的字符串拼接和某列全部填一样的值
- 计算机画图城堡作品,我的世界:红石大神作品赏析,需要26分钟才能逛完的机关城堡...
- Ubuntu 安装qq2015
- vmware converter p2v windows2008R2