GeddyJS, MongoDB, and Querying Subdocs? Try Mongoose

For the past few months I’ve been working on studying NodeJS. Currently, I’m trying to work with the GeddyJS Framework (geddyjs.org). Now they have a database agnostic ORM built into it that can support the likes of MySQL and PostgreSQL but also MongoDB and even flat files.

Unfortunately, there are some things that can’t work very well with the built in ORM (like MongoDB though it does have some functionality) and you might end up on your own there while some things aren’t supported. Now it’s still possible to use a different ORM so don’t npm remove yet!

For example, you have a schema that looks like this:

var Deck = function () {

  this.defineProperties({
    title: {type: 'string', required: true},
    cards: {type: 'object', objectProp: [{name: 'string', type: 'string', id: 'string'}]}
  });

...

Now let’s say you wanted to find all Decks that had a certain card name in it. You can’t use the built in Geddy Model ORM for that yet.

Come in MongooseJS (mongoosejs.com). Actually you can use any other ORM for that matter but for simplicity’s sake let’s use Mongoose.

In your deck controller, let’s say you may have a GET parameter for the index action. Otherwise, it just lists down everything. So if there’s a GET parameter “card”, then you run the query using mongoose. In this example, if there’s no card parameter, the Geddy ORM is used instead.

var mongoose = require('mongoose');

var Decks = function () {
  this.respondsWith = ['html', 'json', 'xml', 'js', 'txt'];

  this.index = function (req, resp, params) {
    var self = this;

    if(params.card) { // If card is specified, use mongoose
      // Connect to mongoose
      mongoose.connect('mongodb://localhost/sampledb');

      // Create Deck Schema
      var Deck = mongoose.model('Deck', { title: String, cards: [{name: String, type: String, id: String}] });

      // RegExp used for ignore case
      Deck.find({'cards.name': new RegExp('^'+params.card+'$', "i")}, function(err, decks) {
        if (err) {
          throw err;
        }

        // Must add model type for each deck
        decks.forEach(function(deck) {
          deck.type = 'Deck';
        });

        self.respondWith(decks, {type:'Deck'});
      });
    } else { // No card param. Use Geddy ORM
      geddy.model.Deck.all(function(err, decks) {
        if (err) {
          throw err;
        }

        self.respondWith(decks, {type:'Deck'});
      });
    }
  };

...

IMPORTANT: I just put in all the mongoose code inside the if statement for example’s sake but don’t initialize schemas in your controller. Please observe best practices and I highly suggest you have a different setup for your Mongoose schema and models and then just import them into your controller (lines 10-14).

Related Posts

Leave a comment

Time limit is exhausted. Please reload the CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Privacy Preferences
When you visit our website, it may store information through your browser from specific services, usually in form of cookies. Here you can change your privacy preferences. Please note that blocking some types of cookies may impact your experience on our website and the services we offer.