简体   繁体   中英

What is “Schema” class used for in Mongoose?

I'm starting to learn Mongoose and I have a question.

In the documentation there are many places where we create a schema with new Schema syntax. For example:

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

and then use it:

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

But on the Mongoose's main page there is an example without it. We just put an object as a second argument of mongoose.model :

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

What is Schema class used for? What is the difference of this two approaches?

Do you want to re-use the schema somewhere else? Do you also realize that abstracting embedded statements lead to cleaner code?

The main difference is re-use where you want to actually do that. The second difference is that a separate declaration is generally easier to read and understand.

This is really more of a "coding style" question, and therefore to try and keep it away from "voicing and opinion" only I am largely pointing out the "re-use" point.

Another factor to consider is that all of these things are really just object constructors it does not mean you need to use it that way as a "hardcoded" approach. Consider loading all schema and model information from a "config file" for example:

As a config file:

{

  "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" }
  }

}

And as a processor:

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;

  }
);

Just a basic example, but there is a clear reason for the general separation as in the way you can actually use it.

So if your question really is "Why are there two ways to do it?", then I can say for one that there are actually many ways to do it and not just two. Frameworks and libraries should not "lock you in" to a specific way of doing things. They should be free to use in the way that suits you best.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM