文章来自
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(' Title:', this.name);
console.log(' ISBN:', 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