Mongoose使用

文章来自
Mongoose基础入门
Mongoose的API
Mongoose模式扩展
指南之查询
指南之验证

mongoose方法很多,很乱,版本不一样,有些方法可能都过时了,所以整理了很久

连接数据库
先下插件,目录创建一个mongoose文件夹,mongoose文件夹里有一个入口的 index.js 和一个 model 文件夹

// mongoose/index.js

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/app',{useNewUrlParser:true,useUnifiedTopology: true},function(err){
    if(err){
        console.log('Connection Error:' + err)
    }else{
        console.log('mongoose Connection success!')
    }
});

module.exports = mongoose;
// app.js

// 启动的时候连接一下mongodb,不需要使用 koa.use
const mongoose = require('./src/mongoose')  

整个操作流程分为

  • 创建Schema和校验器
  • 由Schema创建model
  • 操作【分为存和查】,那删和改呢,其实删和改都是需要先查的

创建Schema,由Schema创建model

// mongoose/model/blog.js

var mongoose = require('mongoose');

var blogSchema = new mongoose.Schema({
    title:  String,
    comments: [{ body: String, date: Date }],
    date: { type: Date, default: Date.now },
    hidden: Boolean,
    meta: {
        votes: Number,
        favs:  Number
  }
})

// 这种写法是创建一个test的model,并且接下来的操作是执行到tests表里
var blogModel = mongoose.model('test', blogSchema);

// 这种写法是创建一个test的model,并且接下来的操作是执行到test表里
var blogModel = mongoose.model('test', blogSchema,'test');

module.exports = blogModel;

操作之存

  • save
  • insertMany
var blogModel = require("mongoose/model/blog").blogModel;

# 插入一条数据用Entity + save
var blogEntity = new blogModel({
    title:  "Mongoose",
    author: "L",
    body:   "Documents are instances of out model. Creating them and saving to the database is easy",
    comments: [{ body: "It's very cool! Thanks a lot!", date: "2014.07.28" }],
    hidden: false,
    meta: {
        votes: 100,
        favs:  99
    }
});

blogEntity.save(function(err, docs){
    if(err) console.log(err);
    console.log('保存成功:' + docs);
});


# 多条数据插入,将多条数据一次性插入,相对于循环使用create保存会更加快,但是没有数据校验
blogModel.insertMany([
    {title: "mongoose1", author: "L"}, 
    {title: "mongoose2", author: "L"}
    ], function(err, docs){
        if(err) console.log(err);
        console.log('保存成功:' + docs);
});

操作之查
下面的方法都属于query的链式查询方法

// 找的方法
Query.prototype.find()  // 找,传字符串是找这个字段后面接判断方法,传键值对是找到key等于这个value的值,传数组是并且条件表示and
Query.prototype.where() // 同上
Query.prototype.count() // 数量
Query.prototype.distinct() //去重
Query.prototype.exists() // 存在
Query.prototype.gt() //大于
Query.prototype.gte() //大于等于
Query.prototype.all() // 全存在
Query.prototype.in() // 存在一个
Query.prototype.nin() // 不在这里
Query.prototype.limit() // 分页
Query.prototype.lt() // 小于
Query.prototype.lte() // 小于等于
Query.prototype.ne() // 不等于
Query.prototype.or() // 二选一
Query.prototype.regex() // 正则,模糊查询
Query.prototype.select() // 选择部分字段
Query.prototype.size() // 
Query.prototype.skip() // 跳过
Query.prototype.slice() // 切断
Query.prototype.sort() // 排序

// 操作的方法
Query.prototype.updateOne()
Query.prototype.updateMany()
Query.prototype.removeOne()
Query.prototype.removeMany()

// 上面写完后是不会执行的,执行有两种写法
// 回调,callback里callback
query.exec(callback)
// promise链式调用,callback里返回另一个query,就可以继续then
query.then(callback)
// promise改进版,async+await
async function init() {
    var A = await model.updateMany({'name':"name2"})
    console.log(A)
}

自定义query方法

userSchema.query.byName = function (name){
  return this.find({name});
}
var model= mongoose.model('model', userSchema);
model.find().byName('pdt1997').exec(callback)

效验器

// required,Number(max,min),String(enum,match)

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 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;
    },
    get: function(url){
      if(!url) return url;
      if(0 !== url.indexOf('http://') && 0 !== url.indexOf("https://"))
        url = 'http://' + url;
      return url;
    }
  }
});

索引

var BookSchema = new mongoose.Schema({
  isbn: {
    type: Number,
    // 唯一索引,可以用来检查是否唯一
    unique: true
  }, 
  name: {
    type: String,
    // 辅助索引,完全是为了增加查询速度
    index: true
  }
});

自定义静态方法
在Schema添加,在model调用

// 做一个分页
userSchema.statics.paginate = function (conditons={},skip = 0,limit = 1){
  return this.find(conditons).skip(skip).limit(limit);
}
var model= mongoose.model('model', userSchema);
model.paginate({},getSkip(1),limit).then((docs)=>{
    console.log("第1页",docs);
});

自定义实例方法
在Schema添加,在Entity调用

BookSchema.methods.print = function(){
  console.log('Book Information:');
  console.log('\tTitle:', this.name);
  console.log('\tISBN:', this.isbn);
};
var book = new Book({
  name: 'MEAN Web Development',
  isbn: 9787100
});
book.print()

前后钩子
又叫中间件

// 文档中间件(init/validate/save/remove)
// 查询中间件(count/find/findOne/findOneAndRemove/findOneAndUpdate/update)
// 做某些特定查询操作的时候会调用的中间件

// pre
var schema = new mongoose.Schema({ age:Number, name: String,x:Number,y:Number});  
schema.pre('find',function(next){
    console.log('我是pre方法1');
    next();
});
schema.pre('find',function(next){
    console.log('我是pre方法2');
    next();
});  
var temp = mongoose.model('temp', schema);
temp.find(function(err,docs){
    console.log(docs[0]);
})    
// 我是pre方法1
// 我是pre方法2
// { _id: 5972ed35e6f98ec60e3dc886,name: 'huochai',age: 27,x: 1,y: 2 }

// post
var schema = new mongoose.Schema({ age:Number, name: String,x:Number,y:Number});  
schema.post('find',function(docs){
    console.log('我是post方法1');
});
schema.post('find',function(docs){
    console.log('我是post方法2');
});
var temp = mongoose.model('temp', schema);
temp.find(function(err,docs){
    console.log(docs[0]);
}) 
// { _id: 5972ed35e6f98ec60e3dc886,name: 'huochai',age: 27,x: 1,y: 2 }
// 我是post方法1
// 我是post方法2
posted @ 2020-01-29 15:51  一个年轻淫  阅读(463)  评论(0编辑  收藏  举报