Is it possible for Mongoose to automatically extract schemas from Mongodb?

Alice Source

I'm still learning Mongodb, Nodejs, and Mongoose, so please excuse my ignorance if this question lacks understanding.

I find it somewhat redundant that each Mongodb collection have to be dissected in Mongoose. Specifically, all the fields of each Mongodb collection and their types need to be stated in Mongoose's schema.

So if I have a collection that contains documents sharing the same fields, such as:

> db.people.find()
    { "_id" : ObjectId("1111"), "name" : "Alice", "age": 30 }
    { "_id" : ObjectId("2222"), "name" : "Bob", "age": 25 }
    { "_id" : ObjectId("3333"), "name" : "Charlie", "age": 40 }

The way that Mongoose+Nodejs connect to this Mongodb

var mongoose = require('mongoose');
var personSchema = new mongoose.Schema({
    name     : String,
    age      : Number
mongoose.model("Person", personSchema, 'people');

where the last line contains the collection name as the 3rd parameter (explained here).

Is it possible to have Mongoose automatically extract the schema somehow from a Mongodb collection for a collection that contains documents of identical fields (i.e. they would have the same schema)? So that we don't have to define the schema in Mongoose.



answered 5 years ago WiredPrairie #1

Mongoose does not currently have a way of automatically building a Schema and Model given an example document.

While a simple document to Schema tool could be written and it would handle some cases reasonably well, depending on the nature of the collections and documents in your database, it wouldn't accurately reflect various aspects of the data model.

For example, if you had two collections that were related:

var personSchema = Schema({
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]


var storySchema = Schema({
  title    : String
  author   : String

As you can see the stories field is an array of ObjectIds that are associated with the story collection. When stored in the MongoDB collection, it would be something like:

    "_id" : ObjectId("52a1d3601d02442354276cfd"),
    "name" : "Carl",
    "age" : 27,
    "stories" : [

And stories:

    "_id" : ObjectId("52a1d33b1d02442354276cfc"),
    "title" : "Alice in Wonderland",
    "author" : "Lewis Carroll"

As you can see, the stories array contains only an ObjectId without storing what it maps to (a document in the stories collection). One functionality of Mongoose that's lost without this connection being established in the schema is populate (reference).

Maybe more importantly, part of the benefit of using Mongoose is to have a declared schema. While it may be "NoSQL" and MongoDB allows documents to be schema-less, many of the drivers in fact encourage developers to have a schema as it helps enforce a consistent document structure in a collection. If you're doing "production" development, having a declared rathered than inferred schema just seems prudent to me. While you can use a design document, having a rigid Schema defined in source code makes it not only the design, but also helps to enforce the Schema from being inadvertently changed.

It's quite easy to declare a Schema in Mongoose and it only needs to be done once per application instance.

You can of course use the underlying driver for MongoDB on NodeJS which doesn't have schema support at all.

comments powered by Disqus