mongoose 学习

mongoose 基础

介绍

  • Mongoose 是一个让我们可以通过Node来操作MongoDB数据库的一个模块
  • Mongoose 是一个对象文档模型(ODM)库,它是对Node原生的MongoDB模块进行了进一步的优化封装
  • 大多数情况下,他被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型装换等好处
  • 基于MongoDB驱动,通过关系型数据库的思想来实现非关系型数据库

优势/好处

  1. 为文档创建模式结构(Schema),也可以说是约束
  2. 对模型中的对象/文档进行验证
  3. 数据可以通过类型装换装换为对象模型
  4. 可以使用中间件来应用业务逻辑挂钩
  5. 相比MongoDB驱动更容易

new Object

  • Schema(模式对象)

    ——Schema 对象定义约束了数据库中的文档结构

  • Model

    ——Model 对象作为集合中的所有文档的表示,相当于MongoDB中的collection,它的每一个实例就是一个document文档

  • Document

    ——Document表示集合中的具体文档,相当于collection中的一个具体文档

  • 关系:Schema生成Model,Model创造Document

简单使用

前提:安装MongoDB,Nodejs

  1. 下载安装Mongoose

    npm i mongoose --save

  2. 项目中引入mongoose

    var mongoose = require(‘mongoose’)

  3. 连接MongoDB数据库

    mongoose.connect(‘mongodb://数据库ip地址 : 端口号( 默认端口27017可以省略 )/数据库名’)

    数据库连接状态

    • connect()返回的是一个待定状态,在mongoose中有一个属性叫 connection 用来表示数据库的连接

    • 通过监视该对象可以用来监听数据库的连接与断开

    • 数据库连接成功事件

      mongoose.connection.once(‘open’ , () => {})

    • 数据库断开事件

      mongoose.connection.once(‘close’ , () => {})

  4. 创建Schema(模式)对象

    var stuSchema = new Schema({})

    • 通过Schema创建Model
    • Model 代表的是数据库中的集合,通过Model才能对数据库进行操作
  5. 映射

    var stuModel = mongoose.model(‘student’,stuSchema)

    参数

    1. 要映射的集合名

    2. 创建的约束(Schema对象)

  6. 通过映射返回的值对数据库进行增、删、改、查

  7. 断开数据库连接(一般不使用)

    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 (快速入门)相关推荐

  1. Mongoose快速入门

    2019独角兽企业重金招聘Python工程师标准>>> Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model : 由Schema发布生成的模型,具 ...

  2. Shiro第一个程序:官方快速入门程序Qucickstart详解教程

    目录 一.下载解压 二.第一个Shiro程序 1. 导入依赖 2. 配置shiro配置文件 3. Quickstart.java 4. 启动测试 三.shiro.ini分析 四.Quickstart. ...

  3. 计算机入门新人必学,异世修真人怎么玩?新手快速入门必备技巧

    异世修真人怎么快速入门?最近新出来的一款文字修仙游戏,很多萌新不知道怎么玩?进小编给大家带来了游戏新手快速入门技巧攻略,希望可以帮到大家. 新手快速入门攻略 1.开局出来往下找婆婆,交互给点钱,旁边有 ...

  4. Spring Boot 2 快速教程:WebFlux 快速入门(二)

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘 ...

  5. Apache Hive 快速入门 (CentOS 7.3 + Hadoop-2.8 + Hive-2.1.1)

    2019独角兽企业重金招聘Python工程师标准>>> 本文节选自<Netkiller Database 手札> 第 63 章 Apache Hive 目录 63.1. ...

  6. 《iOS9开发快速入门》——导读

    本节书摘来自异步社区<iOS9开发快速入门>一书中的目录,作者 刘丽霞 , 邱晓华,更多章节内容可以访问云栖社区"异步社区"公众号查看 目 录 前 言 第1章 iOS ...

  7. BIML 101 - ETL数据清洗 系列 - BIML 快速入门教程 - 序

    BIML 101 - BIML 快速入门教程 做大数据的项目,最花时间的就是数据清洗. 没有一个相对可靠的数据,数据分析就是无木之舟,无水之源. 如果你已经进了ETL这个坑,而且预算有限,并且有大量的 ...

  8. python scrapy菜鸟教程_scrapy学习笔记(一)快速入门

    安装Scrapy Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv.json等文件中. 首先我们安装Scrapy. pip install sc ...

  9. OpenStack快速入门

    OpenStack云计算快速入门(1) 该教程基于Ubuntu12.04版,它将帮助读者建立起一份OpenStack最小化安装.我是五岳之巅,翻译中多采用意译法,所以个别词与原版有出入,请大家谅解.我 ...

  10. Expression Blend实例中文教程(2) - 界面快速入门

    上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习. 在开始使用Ble ...

最新文章

  1. java udp tcp协议_【java】TCP和UDP传输协议
  2. 重载函数与函数模板(转)
  3. C# NameValueCollection集合 (转)
  4. 使用jquery制作计算器_如何使用jQuery对计算器进行编程
  5. [转]Android应用的自动更新
  6. Python 源码剖析(二)—— 第一次修改 Python 源代码
  7. open_cursors参数设置调优
  8. 新潮科技:人工智能歌词创作软件app,在线ai作词押韵写歌词,可以自己写歌词的软件
  9. 欧瑞变频器800参数设置_(完整版)ACS800变频器参数设定
  10. php里无法找到该网页,thinkphp搭建网站后端,入口文件找不到(无法加载)
  11. html图片橡皮擦特效,原生制作的js涂鸦画板特效 可调画笔颜色|粗细|橡皮檫功
  12. method call expected
  13. 关于RedisPool配置参数
  14. unity3d:win32api,托盘运行,开机自启动,浏览文件对话框,无标题栏,自定义标题栏拖动
  15. CentOS7 开启 BBR 加速
  16. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十四) Be careful!前方怪物出没
  17. java毕业设计——基于java+Servlet+jsp的网上花店销售系统设计与实现(毕业论文+程序源码)——网上花店销售系统
  18. AD中出现off grid pin问题的解决方法
  19. 洛谷P5266 学籍管理
  20. python爬取身份证信息、爬取ip代理池

热门文章

  1. 抖音、微信关闭个性化推荐功能上线,用户真能摆脱“算法牢笼”吗?
  2. mrtg监控linux主机的甚至,windows上mrtg监控linuxcpu 内存
  3. 查询网站服务器存放地址,服务器存放地址查询
  4. Google Talk可以使用了(我的试用手记)
  5. H.264的DTS、PTS、frame_num、poc
  6. 翻斗式雨量计(脉冲型)是如何计算出降雨量的?
  7. excel的字符串拼接和某列全部填一样的值
  8. 计算机画图城堡作品,我的世界:红石大神作品赏析,需要26分钟才能逛完的机关城堡...
  9. Ubuntu 安装qq2015
  10. vmware converter p2v windows2008R2