美文网首页
Mongoose 模式扩展

Mongoose 模式扩展

作者: 丹丹十个胆小鬼 | 来源:发表于2018-11-06 17:35 被阅读0次

一、模式扩展

1、默认值

var mongoose = require('mongoose');

mongoose.connect('mongodb://localost/testDB');

var UserSchema = new mongoose.Schema({
  nickname: {
    type: String,
    // 固定值的默认值
    default: 'new user'
  },
  regTime: {
    type: Date,
    // 根据时间生成的默认值
    default: Date.now
  }
});

var User = mongoose.model('User', UserSchema);

var user = new User();

console.log('user: ', user);

2、模式修饰符

模式修饰符包含:

  • 预定义模式修饰符
  • 自定义setter修饰符
  • 自定义getter修饰符
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/testDB');

var User = mongoose.model('User', {
  nickname: {
    type: String,
    // 预定义的修饰符
    // 效果:消除字符串前后的空格
    trim: true
  },
  blog: {
    type: String,
    // 自定义的 setter 修饰符
    set: function(url){
      if(!url) return url;

      if(0 !== url.indexOf('http://') && 0 !== url.indexOf('https://'))
        url = 'http://' + url;

      return url;
    }
  }
});

var user = new User({
  nickname: "   zhang   ",
  blog: 'example.com'
});

console.log('user:', user);

存储时没有添加特定的内容,取出时自动添加

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/testDB');

var User = mongoose.model('User', {
  blog: {
    type: String,
    //自定义的 getter 修饰符
    get: function(url){
      if(!url) return url;

      if(0 !== url.indexOf('http://') && 0 !== url.indexOf("https://"))
        url = 'http://' + url;

      return url;
    }
  }
});

var user = new User({
  blog: 'example.com'
});

user.save(function(err){
  if(err) {
    return console.log('save error:' , err);
  }

  console.log('exampleurl: ', user.blog);
});

3、虚拟属性

有些东西我们并不需要存储到数据库,可以通过其他的属性演算或者通过其他的办法来得到这个属性值,虽然不存储这个属性,但是通过其他的转换让它跟其他的属性没有区别,这就是虚拟属性。

var mongoose = require('mongoose');

var PersonSchema = new mongoose.Schema({
  fristName: String,
  lastName: String
});

// 虚拟属性的设置
PersonSchema.virtual('fullName').get(function(){
  return this.fristName + ' ' + this.lastName;
});

// 在将对象转换为 json 时,设置同时也要转换虚拟属性的值
// 如果不设置,对象中将不会添加这个虚拟属性
PersonSchema.set('toJSON', {getters: true, virtual: true});

var Person = mongoose.model('Person', PersonSchema);

var person = new Person({
  fristName: 'zhang',
  lastName: 'san'
});

console.log('user fullName:', person.fullName);

console.log('JSON:', JSON.stringify(person));

4、索引

唯一索引:可以用来检查是否唯一
辅助索引:完全是为了增加查询速度

var mongoose = require('mongoose');

var BookSchema = new mongoose.Schema({
  isbn: {
    type: Number,
    // 唯一索引
    unique: true
  }, 
  name: {
    type: String,
    // 辅助索引
    index: true
  }
});

二、模型方法

可以自定义静态方法和实例方法

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/part10');

var BookSchema = new mongoose.Schema({
  name: String,
  isbn: Number
});

// 静态方法
BookSchema.statics.findByISBN = function(isbn, cb){
  this.findOne({isbn: isbn}, function(err, doc){
    cb(err, doc);
  });
};

// 实例方法
BookSchema.methods.print = function(){
  console.log('Book Information:');
  console.log('\tTitle:', this.name);
  console.log('\tISBN:', this.isbn);
};

var Book = mongoose.model('Book', BookSchema);

var book = new Book({
  name: 'MEAN Web Development',
  isbn: 9787100
});

book.save(function(err){
  if(err) {
    return console.log('save book failed', err);
  }

  Book.findByISBN(9787100, function(err, doc){
    console.log('findByISBN, err, doc:', err, doc);
  });
  // 调用实例方法
  book.print();
});

三、数据的校验

  • 预定义验证器
    required,Number(max,min),String(enum,match)
  • 自定义验证器
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/part10');

var OrderSchema = new mongoose.Schema({
  count: {
    type: Number,
    // 是否必须的校验器
    required: true,
    // 数字类型的最大值校验器
    max: 1000,
    // 数字类型的最小值校验器
    min: 10
  },
  status: {
    type: String,
    // 设置字符串的可选值
    enum: ['created', 'sucess', 'failed']
  },
  desc: {
    type: String,
    // 使用正则表达式来校验字符串的内容
    match: /book/g,
    // 自定义的验证器,如果通过验证返回 true,没有通过则返回 false
    validate: function(desc) {
      return desc.length >= 10;
    }
  }
});

var Order = mongoose.model('Order', OrderSchema);

var order = new Order();
order.count = 10;
order.status = 'created';
order.desc = 'this is a great book';
order.save(function(err){

  if(err) {
    return console.log('save failed:', err);
  }

  console.log('save success');
});

四、中间件

  • 文档中间件(init/validate/save/remove)
    当我们的文档做某一个特定操作会触发的中间件,
  • 查询中间件(count/find/findOne/findOneAndRemove/findOneAndUpdate/update)
    做某些特定查询操作的时候会调用的中间件

从执行的时机上讲,分为两类

  • 预处理中间件
    在操作做之前要处理的中间件
  • 后置处理中间件
    操作后要执行的中间件
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/part10');

var ResellerSchema = new mongoose.Schema({
  address: String
});

// 普通的中间件
ResellerSchema.post('save', function(next){
  console.log('this is ResellerSchema post save middleware');
  next();
});

// 可以并行执行的中间件
ResellerSchema.pre('save', true, function(next, done){
  console.log('this is ResellerSchema pre save middleware');
  next();
  // done 需要传给并行执行的方法或者过程,当该并行执行的方法或过程完成执行之后,调用 done
  // 以通知 mongoose 执行完成。
  done();
});

var Reseller = mongoose.model('Reseller', ResellerSchema);

var reseller = new Reseller({
  address: '101st, People Read'
});

reseller.save();

五、DBRef

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/part10');

var User = mongoose.model('User', {
  username: String
});

var News = mongoose.model('News', {
  title: String,
  // DBRef 的定义
  author: {
    type: mongoose.Schema.ObjectId,
    ref: 'User'
  }
});

var user = new User({
  username: 'Sid'
});

var news = new News({
  title: 'Congratulation!',
  author: user
});

user.save(function(err){
  if(err) {
    return console.log('save user failed:', err);
  }

  news.save(function(err){
    if(err) {
      return console.log('save news failed:', err);
    }

    // 使用 populate() 方法填充数据
    News.findOne().populate('author').exec(function(err, doc){
      console.log('after populate: ', err, doc);
    });
  });
})

相关文章

网友评论

      本文标题:Mongoose 模式扩展

      本文链接:https://www.haomeiwen.com/subject/vswuxqtx.html