什么是Mongoose中使用的“Schema”类?

时间:2014-08-04 10:52:44

标签: javascript node.js mongodb mongoose

我开始学习猫鼬,我有一个问题。

在文档中,有很多地方我们使用new Schema语法创建模式。例如:

var blogSchema = new Schema({
  title:  String,
  author: String,
  //other fields
});

然后使用它:

var Blog = mongoose.model('Blog', blogSchema);

但在Mongoose's main page上有一个没有它的例子。我们只是将一个对象作为mongoose.model的第二个参数:

var Cat = mongoose.model('Cat', { name: String });

Schema课程用于什么?这两种方法有什么区别?

1 个答案:

答案 0 :(得分:2)

您想在其他地方重新使用架构吗?您是否也意识到抽象嵌入语句会导致更清晰的代码?

主要区别在于您希望实际执行此操作的重复使用。第二个区别是单独的声明通常更容易阅读和理解。

这实际上更像是一种编码风格"问题,因此要尽量远离"表达和意见"只是我在很大程度上指出了重复使用"点。

要考虑的另一个因素是,所有这些事情都只是对象构造函数,并不意味着您需要以这种方式使用它作为"硬编码的"做法。考虑从"配置文件中加载所有模式和模型信息"例如:

作为配置文件:

{

  "Schema": {

    "ownerSchema": {
      "name": { "type": "String" },
      "email": { "type": "String" },
      "accounts": [{ "type": "ObjectId", "ref": "Account" }]
    },

    "transactionSchema": {
      "account": { "type": "Number" },
      "added": { "type": "Date" }
    },

    "recentBucketSchema": {
      "_id": { "type": "ObjectId", "ref": "AccountBucket" },
      "day": { "type": "Date" }
    },

    "accountSchema": {
      "owner": { "type": "ObjectId", "ref": "Owner" },
      "balance": { "type": "Number", "default": 0 },
      "recent": [{ "schema": "recentBucketSchema" }]
    },

    "accountBucketSchema": {
      "day": { "type": "Date" },
      "account": { "type": "ObjectId", "ref": "Account" },
      "owner": { "type": "ObjectId", "ref": "Owner" },
      "balance": { "type": "Number", "default": 0 },
      "transactions": [{ "schema": "transactionSchema" }]
    }

  },

  "Models": {
    "Owner": { "schema": "ownerSchema" },
    "Account": { "schema": "accountSchema" },
    "AccountBucket": { "schema": "accountBucketSchema" }
  }

}

作为处理器:

var async = require('async'),
    fs = require('fs'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;


function ReturnType(type) {
  switch(type) {
    case "String":
      return String;
    case "Number":
      return Number;
    case "Date":
      return Date;
    case "ObjectId":
      return Schema.Types.ObjectId;
  }
}

function ParseSchema(schema,data) {
  for ( k in schema ) {
    var outerType = Object.prototype.toString.call( schema[k] );
    if ( outerType !== "[object Array]" ) {
      schema[k].type = ReturnType(schema[k].type);
    } else {
      if ( schema[k][0].hasOwnProperty("schema") ) {
        schema[k][0] = ParseSchema(data.Schema[schema[k][0].schema],data)
      } else {
        schema[k][0].type = ReturnType(schema[k][0].type);
      }
    }
  }
  return new Schema( schema );
}

async.waterfall(
  [
    function(callback) {
      var file = __dirname + '/sample.json';
      fs.readFile(file, 'utf8', function(err,data) {
        if (err)
          callback(err);

        callback(err,JSON.parse(data));

      });
    },

    function(data,callback) {
      async.each( Object.keys( data.Models ), function(modelName,callback) {
        var currentSchema = data.Schema[data.Models[modelName].schema];

        currentSchema = ParseSchema(currentSchema,data);
        mongoose.model( modelName, currentSchema );
        callback();

      },function(err) {
        callback();
      });
    }
  ],
  function(err) {
    if (err)
      throw err;

  }
);

只是一个基本的例子,但是有一个明确的理由可以像实际使用它一样进行一般分离。

所以,如果你的问题真的是"为什么有两种方法可以做到?",那么我可以说一个实际上有很多的方法来实现它不只是两个。框架和图书馆不应该将您锁定在"以某种特定的方式做事。它们应该以最适合您的方式自由使用。