一、Schema
schema 定义 documents的基本字段和集合;mongoose提供了Schema类
-
mongoose支持的基本类型
String、Number、Boolean、Date、Buffer、Array、Objected、Mixed
-
mongoose设置索引
1)在Schema filed中设置
var animalSchema = new Schema({
name: String,
type: String,
tags: { type: [String], index: true }
});
2)在Schema.index中设置
//在Schema.index中设置
animalSchema.index({ name: 1, type: -1 });
//1 表示正序, -1 表示逆序
- mongoose连接
mongoose.connect('mongodb://user:pass@localhost:port/database', { config: { autoIndex: false } });
animalSchema.set('autoIndex', false); //推荐
- Schema.methods
// 添加fn
animalSchema .methods.findSimilarTypes =function(cb){
// this指具体的doc
return this.model('Animal').find({ type: this.type }, cb)
}
// 该method实际上是绑定在实例的 doc上的
定义完methods和property之后, 就到了生成Model的阶段了.
只需要使用mongoose.model()即可
- 实例Model
// 生成model类
var Animal = mongoose.model('Animal', animalSchema)
var dog = new Animal({ type: 'dog' });
Schema.methods.fn
定义的方法只能new Model()实例
中访问;如果想直接在Model上调用,则需要使用statics
绑定Model方法
// 给model添加一个findByName方法
animalSchema.statics.findByName = function (name, cb) {
//这里的this 指的就是Model
return this.find({ name: new RegExp(name, 'i') }, cb);
}
var Animal = mongoose.model('Animal', animalSchema);
Animal.findByName('fido', function (err, animals) {
console.log(animals);
});
- Schema初始化参数
- safe 设置安全模式
var safe = true
new Schema({ .. }, { safe: safe });
- 自定义安全模式
var safe = {w:"majority", wtimeout: 10000}
new Schema({ .. }, { safe: safe });
- toObject
schema.set('toObject', { getters: true });
var M = mongoose.model('Person', schema);
var m = new M({ name: 'Max Headroom' });
- toJSON
二、Model
- model的创建
model的创建实际上就是方法的copy. 将schema上的方法,copy到model上. 只是copy的位置不一样, 一部分在prototype上, 一部分在constructor中
// 数据库操作
const mongoose = require('mongoose');
// 模型规则类
const { Schema } = mongoose;
// 模型规则
var CategorySchema= new Schema({ name: 'string', size: 'string' });
// 创建集合
const Category = mongoose.model('Category', CategorySchema);
Category实际在db中的collection是’Categorys’
- model的子文档操作
// 定义schema
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
children: [childSchema] //指明sub-doc的schema
});
// 创建model
var Parent = mongoose.model('Parent', parentSchema);
// modedl实例
var parent = new Parent({ children: [{ name: 'Matt' }, { name: 'Sarah' }] })
parent.children[0].name = 'Matthew';
parent.save(callback);
- 子文档的CRUD
数组操作:push,unshift, remove, pop, shift
parent.children.push({ name: 'Liesl' });
// 删除
var doc = parent.children.id(id).remove();
// 新增
var newdoc = parent.children.create({ name: 'Aaron' });
- model创建
1)实例
var Tank = mongoose.model('Tank', yourSchema);
var small = new Tank({ size: 'small' });
//使用实例创建
small.save(function (err) {
if (err) return handleError(err);
// saved!
})
2)Model
//使用Model类创建
Tank.create({ size: 'small' }, function (err, small) {
if (err) return handleError(err);
// saved!
})
model的query model的查找主要提供了以下的API:
find, findById, findOne, or where
,返回JSON数据
- 在mongoose中,query数据 提供了两种方式
- callback:使用回调函数,立即执行
Person.findOne({ 'name.last': 'Ghost' }, 'name occupation', function (err, person) {
if (err) return handleError(err);
// get data
})
- query:返回Promise对象,可以使用链式调用,最后必须使用exec(cb)传入回调处理
第一个参数必须是err,第二个参数是返回的数据
User.find({age: {$gte: 21, $lte: 65}}, callback);
//等价于:
User.where('age').gte(21).lte(65).exec(callback);
validation
monoose里的中间件
- pre:在指定方法执行之前绑定。 中间件的状态分为
parallel
和series
- post:相当于事件监听的绑定
中间件一般仅限用于几个方法:
- doc 方法上:
init,validate,save,remove;
- model方法上:
count,find,findOne,findOneAndRemove,findOneAndUpdate,update
1. pre
// series执行, 串行
var schema = new Schema(..);
schema.pre('save', function(next) {
// exe some operations
this.model.
next(); // 这里的next()相当于间执行权给下一个pre
});
在你调用 model.save方法时, 他会自动执行pre. 如果你想并行执行中间件, 可以设置为:
schema.pre('save', true, function(next, done) {
// 并行执行下一个中间件
next();
});
2. post
schema.post('save', function(doc) {
//在save完成后 触发.
console.log('%s has been saved', doc._id);
});
当save方法调用时, 便会触发post绑定的save事件. 如果你绑定了多个post。 则需要指定一下中间件顺序.
schema.post('save', function(doc, next) {
setTimeout(function() {
console.log('post1');
next();
}, 10);
});
schema.post('save', function(doc, next) {
console.log('post2');
next();
});