MongoDB “Eager Fetching” Workaround in GeddyJS

As you all know, there’s no such thing as a JOIN in MongoDB. The burden of applying logic is on the application side.

SQL Adapters (like MySQL and PostgreSQL) have an eager fetching solution from the GeddyJS Model ORM. Eager fetching would look like this (taken from the code sample in the GeddyJS tutorial):

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

  geddy.model.ToDo.all({}, {includes: 'steps'}, function(err, toDos) {
    if (err) {
      throw err;
    }
    self.respondWith(toDos, {type:'ToDo'});
  });
};

This would definitely work for an SQL Adapter.. but what about MongoDB with linked collections? The GeddyJS dev team might put this feature up in the future but it has yet to be done.

So let’s do a workaround for now! Let’s assume that we have two separate models (and collections) named ToDo and Step.

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

  geddy.model.ToDo.all(function (err, todos) {
    todos.forEach(function(todo) {
      todo.getSteps(function (err, steps) {
        todo.steps = steps;
      });
    });

    self.respondWith(todos, {type: 'ToDo'});
  });
});

But wait, there’s more!

There can be a slight performance issue with this and it may be evident in production code. Remember that callbacks are asynchronous and if the callbacks haven’t finished and you already responded, the data might end up as undefined.

How do we handle this properly? Check out this blog post (How to Properly Deal with Javascript Asynchronous Code: Matteo Agosti) which explains how to treat asynchronous code and callbacks in NodeJS.

Now let’s apply it to the code above:

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

  geddy.model.ToDo.all(function (err, todos) {
    todos.forEach(function(todo) {
      todo.getSteps(function (err, steps) {
        todo.steps = steps;
      });
    });

    setTimeout(function() {
      self.respondWith(todos, {type: 'ToDo'});
    }, todos.length * 1000); // Just to factor in length of the todos array
  });
});

Also, if you’d prefer, you can also use a different ORM. Chances are you’ll have to use the same logic for most if not all current MongoDB compatible ORMs however. My previous post talks about using another ORM (Mongoose) to query embedded documents.

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.