Created: 2012-03-23 08:23
Updated: 2013-09-30 05:42


Common Dwarf Mongoose

Common Dwarf Mongoose

Mongoose with some synthetic sugar

Common Dwarf Mongoose is a little wrapper around the excellent Mongoose ORM library. It provides some synthetic sugar like attributes and a more ExtJS/Backbone.js inspired way to define database models.


Installing is very easy, get it from the NPM registry:

npm install common_dwarf_mongoose


Mongoose.Base is the superclass for all database related models.

It combines creation of a Mongo schema and a mongoose model. Additional it provides some synthetic sugar around this:

Let's say, we want to store a collection of authors in our MongoDB.

(Note: Connect to your MongoDB just like this says )

To use Mongoose.Base require the module:

require 'common_dwarf_mongoose'

Define the model:

class Author extends Mongoose.Base
  alias: 'author'

    name    : {type : String, index: true}
    blog    : {type : String, default: ""}
    alive   : {type : Boolean,default: false}

The alias property is used to name the collection. This is done by pluralizing the alias which is inspired by Ruby On Rails in a very simple way:

author => authors
user => users
blog_post => blog_posts

Any options documented from Mongoose are possible with the following deviantions:

  • To use ObjectId use Mongoose.ObjectId
  • To use 'any' Type (Schema.Types.Mixed) use Mongoose.Mixed

The class takes care about reating a schema and a mongoose model as documented here.

With the addition of synthetic sugar it allows us:

author = new Author()
author.set('name':'Jack Kerouac')
author.set('blog':'')> throw err if err)

Mass assignment is not supported at the moment.

Accessing saved authors is also easy. Maybe you know this from ActiveRecord or Backbone.js:

  for authorAsDocument in authorDocuments
    author = Author.becomesFrom(author)
    console.log author.getName()
    console.log author.getBlog()

(Also supported are #findById and findByOne.)

Notice the last two lines before the parenthesis.

Any attribute you define in fields will be accessible with a get prefix after a model is instantiated and an attribute is assigned.


If you define a boolean attribute in fields the getter will be more context understandable:


Another option to get an attribute is calling #get(), which is also well know from backbone.js or ExtJs:

author.get('name') #=> 'Jack Kerouac'

To get all attributes at once, use the #attributes property:

author.attributes #=> {name: 'Jack Kerouac', blog: ''}

If you need a JSON representation of your model's data, you can achieve this with #toJSON() method:

author.toJSON() #=> {'name' : 'Jack Kerouac', 'blog' : ''}


Common Dwarf Mongoose also supports plugins like you know them from mongoose. Adding them to your model is easy as defining fields:

Write a plugin or use an existing one:

lastModified = (schema, options)->
  schema.add({ lastMod: Date })

  schema.pre('save', (next)->
    this.lastMod = new Date

  schema.path('lastMod').index(options.index) if (options && options.index)

Add the plugin to the model:

class Author extends Mongoose.Base
  alias: 'author'

    name    : {type : String, index: true}
    blog    : {type : String, default: ""}
    alive   : {type : Boolean,default: false}

    plugin: lastModified, config: {index: true}

That's it.

Multiple connections

If you have to handle documents scattered at different databases it would be nice to handle this within the model definition. Unfortunately, adding database names to a common_dwarf_mongoose model is not possible due the fact it is mongoose based. But a solution is to add a connection instance to your model.

personnel_db  = mongo.createConnection("mongodb://")
tasks_db      = mongo.createConnection("mongodb://")

class FacilityManager extends Mongoose.Base

  alias: 'manager'

    name    : { type: String, index: true }
    salary  : { type: Number } 

  connection: personnel_db

class Task extends Mongoose.Base

  alias: 'task'

    name    : { type: String,   index: true }
    due_to  : { type: Date,     index:true  }
    done    : { type: Boolean }

Note: If you seperate your database connection handling from defining your models (say other files or modules), connection must be global or otherwise accessable.


To use #where()

 .where('tags').in(['movie', 'music', 'art'])
 . #  select('name', 'age', 'tags')
 .hint({ age: 1, name: 1 })


You can use #count of course.

Mixin support

Common Dwarf Mongoose provides mixin support which is accessible if you require the library:

require 'common_dwarf_mongoose'

Any class which inherits from Mixin.Base could include or extend functionality with JavaScript objects:

Extensions.documentation = 

Extensions.folder = 

class A extends Mixin.Base
  @include Extensions.documentation
  @extend Extensions.folder

class B extends Mixin.Base
  @include Extensions.documentation
  @extend Extensions.folder

a = new A()
b = new B()

console.log a.kind()
console.log b.kind()

console.log A.folderType()
console.log B.folderType()

Common Dwarf Mongoose provides a global namespace called Extensions which could be used to collect all your mixin modules within a single namespace.

Authors and Contributors

Written by Daniel Schmidt(@dsci), Datenspiel GmbH 2012

The picture above was taken by Quartl.

Support or Contact

Having trouble with Common Dwarf Mongoose? Do not hesitate to open an issue at the Issue Tracker :octocat: .

Cookies help us deliver our services. By using our services, you agree to our use of cookies Learn more