转载

Mongoose - 在 NodeJs 中优雅地建立 MongoDb 对象模型

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 类型有:( 了解更多 )

  • String
  • Number
  • Date
  • Buffer
  • Boolean
  • Mixed
  • ObjectId
  • Array
    用法:
  • 自定义方法

    模型的实例都是一个个的文档,文档中自带许多方法。同时,我们也可以定义我们自己的方法。

    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
      具体的配置请移步至 官网
原文  http://jzleung.github.io/2016/08/13/mongoose-guide/
正文到此结束
Loading...