Schema
Everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.
在 Mongoose 中,所有东西都从一个 Schema 开始。每一个 schema 都映射到一个 MongoDb 的集合,并定义了该集合中的文档的形式。
定义一个 Schema:
var Schema = mongoose.Schema; var userSchema = new Schema({ name: String, pass: String, email: String, createTime: Date, lastLogin: Date });
Schema 中的每一个键都定义了一个文档的一个属性。在上面的例子中,我们定义了用户名 name
,它会被映射为 String 的 Schema 类型,注册时间 createTime
会被映射为 Date 的 Schema 类型。
允许的 Schema 类型有:( 了解更多 )
自定义方法
模型的实例都是一个个的文档,文档中自带许多方法。同时,我们也可以定义我们自己的方法。
var userSchema = new Schema({ name: String, pass: String, email: String, createTime: Date, lastLogin: Date, type: String }); //根据该用户的类型区查找该类型下的所有用户 userSchema.methods.findUsersByType = function(name, cb){ return this.find({type: this.type}, cb); } //新建模型 var User = mongoose.model('User', userSchema); //使用 var newUser = new User({...}); newUser.findUsersByType(function(err, users){ err && return console.error(err); console.log(users); })
这样就向 User
的实例添加了一个自定义的方法。
静态方法
同样的,向模型中添加自定义方法也是很简单。
userSchema.statics.findUsersByName = function(name, cb){ return this.find({name: new RegExp(name, "ig")}, cb); } //使用 User.findUsersByName('leung', function(err, users){ err && return console.error(err); console.log(users); })
查询辅助
可以自定义一个查询的辅助函数,它和实体的方法类似,但是供 Mongoose 查询使用。
userSchema.query.byName = function(name){ return this.find({name: new RegExp(name, "ig")}); } //使用 userSchema.find().byName('leung').exec(function(err, users){ err && return console.error(err); console.log(users); })
索引
MongoDb 支持第二个索引,在使用 Mongoose 的时候,可以在定义 Schema 的时候定义索引。
//定义方法1 var userSchema = new Schema({ name: String, pass: String, email: String, createTime: {type: Date, index: true}, lastLogin: {type: Date, index: true}, type: String }); //定义方法2 userSchema.index({ createTime: 1, lastLogin: -1 });
Mongoose 会在程序启动的时候,对于每个定义了索引的字段自动调用 ensureIndex
函数。当在不需要这些索引的时候,可以使用下列 4 种方式关闭索引。
mongoose.connect('mongodb://user:pass@localhost:port/database', { config: { autoIndex: false } }); // or mongoose.createConnection('mongodb://user:pass@localhost:port/database', { config: { autoIndex: false } }); // or userSchema.set('autoIndex', false); // or new Schema({..}, { autoIndex: false });
虚拟字段
虚拟字段可以让你很方便的在文档中存取,但是不会写入数据库中。getter 方法在格式化或者合并字段的时候很有用,而 setter 方法则在反格式化或者时将多个值合并的时候有用。
var personSchema = new Schema({ name:{ firstName: String, lastName: String } }); var Person = mongoose.model('Person', personSchema); //定义虚拟字段 fullName personSchema.virtual('name.fullName').get(function(){ console.log(this); return this.name.firstName + ' ' + this.name.lastName; }) var me = new Person({name: {firstName: 'zhong', lastName: 'Lueng'}}); console.log(me); console.log(me.name.fullName) //zhong Lueng
虚拟字段的 setter 方法会在其他校验前使用,因此,即使字段时必须的,虚拟字段也会正常执行。
配置项
Schema 有许多可配置的配置项,可以在新建 Schema 时或者直接设置。
new Schema({..}, options); //or var schema = new Schema({..}); schema.set(option, value);
有效的配置项:
autoIndex
capped
collection
emitIndexErrors
id
_id
minimize
read
safe
shardKey
strict
toJSON
toObject
typeKey
validateBeforeSave
versionKey
skipVersioning
timestamps