Mongoose - 在 NodeJs 中优雅地建立 MongoDb 对象模型
yarhoo
8年前
<p>Schema</p> <p>Everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.</p> <p>在 Mongoose 中,所有东西都从一个 Schema 开始。每一个 schema 都映射到一个 MongoDb 的集合,并定义了该集合中的文档的形式。</p> <p>定义一个 Schema:</p> <pre> <code class="language-javascript">var Schema = mongoose.Schema; var userSchema = new Schema({ name: String, pass: String, email: String, createTime: Date, lastLogin: Date }); </code></pre> <p>Schema 中的每一个键都定义了一个文档的一个属性。在上面的例子中,我们定义了用户名 name ,它会被映射为 String 的 Schema 类型,注册时间 createTime 会被映射为 Date 的 Schema 类型。</p> <p>允许的 Schema 类型有:( <a href="/misc/goto?guid=4959677001857948580" rel="nofollow,noindex">了解更多</a> )</p> <ul> <li>String</li> <li>Number</li> <li>Date</li> <li>Buffer</li> <li>Boolean</li> <li>Mixed</li> <li>ObjectId</li> <li>Array<br> 用法:</li> <li> <p>自定义方法</p> <p>模型的实例都是一个个的文档,文档中自带许多方法。同时,我们也可以定义我们自己的方法。</p> <pre> <code class="language-javascript">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); }) </code></pre> <p>这样就向 User 的实例添加了一个自定义的方法。</p> </li> <li> <p>静态方法</p> <p>同样的,向模型中添加自定义方法也是很简单。</p> <pre> <code class="language-javascript">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); }) </code></pre> </li> <li> <p>查询辅助</p> <p>可以自定义一个查询的辅助函数,它和实体的方法类似,但是供 Mongoose 查询使用。</p> <pre> <code class="language-javascript">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); }) </code></pre> </li> <li> <p>索引</p> <p>MongoDb 支持第二个索引,在使用 Mongoose 的时候,可以在定义 Schema 的时候定义索引。</p> <pre> <code class="language-javascript">//定义方法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 }); </code></pre> <p>Mongoose 会在程序启动的时候,对于每个定义了索引的字段自动调用 ensureIndex 函数。当在不需要这些索引的时候,可以使用下列 4 种方式关闭索引。</p> <pre> <code class="language-javascript">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 }); </code></pre> </li> <li> <p>虚拟字段</p> <p>虚拟字段可以让你很方便的在文档中存取,但是不会写入数据库中。getter 方法在格式化或者合并字段的时候很有用,而 setter 方法则在反格式化或者时将多个值合并的时候有用。</p> <pre> <code class="language-javascript">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 </code></pre> <p>虚拟字段的 setter 方法会在其他校验前使用,因此,即使字段时必须的,虚拟字段也会正常执行。</p> <p>只用非虚拟字段才可以在查询或者字段选择中使用。</p> </li> <li> <p>配置项</p> <p>Schema 有许多可配置的配置项,可以在新建 Schema 时或者直接设置。</p> <pre> <code class="language-javascript">new Schema({..}, options); //or var schema = new Schema({..}); schema.set(option, value); </code></pre> <p>有效的配置项:</p> <ul> <li>autoIndex</li> <li>capped</li> <li>collection</li> <li>emitIndexErrors</li> <li>id</li> <li>_id</li> <li>minimize</li> <li>read</li> <li>safe</li> <li>shardKey</li> <li>strict</li> <li>toJSON</li> <li>toObject</li> <li>typeKey</li> <li>validateBeforeSave</li> <li>versionKey</li> <li>skipVersioning</li> <li>timestamps<br> 具体的配置请移步至 <a href="/misc/goto?guid=4959661534958655105" rel="nofollow,noindex">官网</a></li> </ul> </li> </ul> <p> </p> <p>来自:http://jzleung.github.io/2016/08/13/mongoose-guide/</p> <p> </p>