mongoose中的Schema和Model
Schema
Schema主要用於定義MongoDB中集合Collection裡文件document的結構,可以理解為mongoose對錶結構的定義(不僅僅可以定義文件的結構和屬性,還可以定義文件的例項方法、靜態模型方法、複合索引等),每個schema會對映到mongodb中的一個collection,schema不具備操作資料庫的能力
定義Schema非常簡單,指定欄位名和型別即可,支援的型別包括以下8種
String 字串 Number 數字 Date 日期 Buffer 二進位制 Boolean 布林值 Mixed 混合型別 ObjectId 物件ID Array 陣列
通過mongoose.Schema來呼叫Schema,然後使用new方法來建立schema
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var mySchema = new Schema({ title: String, author: String, body: String, comments: [{ body: String, date: Date }], date: { type: Date, default: Date.now }, hidden: Boolean, meta: { votes: Number, favs: Number } });
注意 建立Schema物件時,宣告欄位型別有兩種方法,一種是首字母大寫的欄位型別,另一種是引號包含的小寫欄位型別
var mySchema = new Schema({title:String, author:String});
//或者
var mySchema = new Schema({title:'string', author:'string'});
如果需要在Schema定義後新增其他欄位,可以使用add()方法
var MySchema = new Schema; MySchema.add({ name: 'string', color: 'string', price: 'number' });
Model
Model是由Schema編譯而成的假想(fancy)構造器,具有抽象屬性和行為。Model的每一個例項(instance)就是一個document,document可以儲存到資料庫和對資料庫進行操作。簡單說就是model是由schema生成的模型,可以對資料庫的操作。
使用model()方法,將Schema編譯為Model。model()方法的第一個引數是模型名稱
mongoose.model(`文件名稱`, Schema)
注意 一定要將model()方法的第一個引數和其返回值設定為相同的值,否則會出現不可預知的結果
Mongoose會將集合名稱設定為模型名稱的小寫版。如果名稱的最後一個字元是字母,則會變成複數;如果名稱的最後一個字元是數字,則不變;如果模型名稱為"MyModel",則集合名稱為"mymodels";如果模型名稱為"Model1",則集合名稱為"model1"
var schema = new mongoose.Schema({ num:Number, name: String, size: String});
var MyModel = mongoose.model('MyModel', schema);
【例項化文件document】
通過對原型Model1使用new方法,例項化出文件document物件
var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:[email protected]/db1", function(err) {
if(err){
console.log('連線失敗');
}else{
console.log('連線成功');
var schema = new mongoose.Schema({ num:Number, name: String, size: String});
var MyModel = mongoose.model('MyModel', schema);
var doc1 = new MyModel({ size: 'small' });
console.log(doc1.size);//'small'
}
});
【文件儲存】
通過new Model1()建立的文件doc1,必須通過save()方法,才能將建立的文件儲存到資料庫的集合中,集合名稱為模型名稱的小寫複數版
回撥函式是可選項,第一個引數為err,第二個引數為儲存的文件物件
save(function (err, doc) {})
var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:[email protected]/db1", function(err) {
if(!err){
var schema = new mongoose.Schema({ num:Number, name: String, size: String });
var MyModel = mongoose.model('MyModel', schema);
var doc1 = new MyModel({ size: 'small' });
doc1.save(function (err,doc) {
//{ __v: 0, size: 'small', _id: 5970daba61162662b45a24a1 }
console.log(doc);
})
}
});
由下圖所示,db1資料庫中的集合名稱為mymodels,裡面有一個{size:"small"}的文件
自定義方法 【例項方法】
Model的例項是document,內建例項方法有很多,如 save,可以通過Schema物件的methods屬性給例項自定義擴充套件方法
var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:[email protected]/db1", function(err) {
if(!err){
var schema = new mongoose.Schema({ num:Number, name: String, size: String });
schema.methods.findSimilarSizes = function(cb){
return this.model('MyModel').find({size:this.size},cb);
}
var MyModel = mongoose.model('MyModel', schema);
var doc1 = new MyModel({ name:'doc1', size: 'small' });
var doc2 = new MyModel({ name:'doc2', size: 'small' });
var doc3 = new MyModel({ name:'doc3', size: 'big' });
doc1.save();
doc2.save();
doc3.save();
setTimeout(function(){
doc1.findSimilarSizes(function(err,docs){
docs.forEach(function(item,index,arr){
//doc1
//doc2
console.log(item.name)
})
})
},0)
}
});
【靜態方法】
通過Schema物件的statics屬性給 Model 新增靜態方法
var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:[email protected]/db1", function(err) {
if(!err){
var schema = new mongoose.Schema({ num:Number, name: String, size: String });
schema.statics.findByName = function(name,cb){
return this.find({name: new RegExp(name,'i')},cb);
}
var MyModel = mongoose.model('MyModel', schema);
var doc1 = new MyModel({ name:'doc1', size: 'small' });
var doc2 = new MyModel({ name:'doc2', size: 'small' });
var doc3 = new MyModel({ name:'doc3', size: 'big' });
doc1.save();
doc2.save();
doc3.save();
setTimeout(function(){
MyModel.findByName('doc1',function(err,docs){
//[ { _id: 5971e68f4f4216605880dca2,name: 'doc1',size: 'small',__v: 0 } ]
console.log(docs);
})
},0)
}
});
由上所示,例項方法和靜態方法的區別在於,靜態方法是通過Schema物件的statics屬性給model新增方法,例項方法是通過Schema物件的methods是給document新增方法
【Methods 和 Statics 的區別】
statics是給model新增方法,methods是給例項(instance)新增方法。methods和statics的區別
//module.exports = mongoose.model(`Article`, ArticleSchema )
//將article的model儲存為檔案 article.js
const Article = require('../models/article')
// statics
Article.staticFunc ()
//methods
const article = new Article(arguments)
article.methodFunc()
【查詢方法】
通過schema物件的query屬性,給model新增查詢方法
var mongoose = require('mongoose');
mongoose.connect("mongodb://u1:[email protected]/db1", function(err) {
if(!err){
var schema = new mongoose.Schema({ age:Number, name: String});
schema.query.byName = function(name){
return this.find({name: new RegExp(name)});
}
var temp = mongoose.model('temp', schema);
temp.find().byName('huo').exec(function(err,docs){
//[ { _id: 5971f93be6f98ec60e3dc86c, name: 'huochai', age: 27 },
// { _id: 5971f93be6f98ec60e3dc86e, name: 'huo', age: 30 } ]
console.log(docs);
})
}
});