Good way to handle Q Promises in Waterline with Sails.js

I have a problem that I'm importing some data and each new row depends on previous row being added (since each row has its order attribute set based on current maximum order from other objects). The flow is that I first try to find object with the same name, if not found I first check maximum order and create new object with order + 1 from that query. I tried doing this with Q promises which are available under Waterline. I tried using all method as well as combining queries with then from Q docs:

var result = Q(initialVal);
funcs.forEach(function (f) {
    result = result.then(f);
});
return result;

But all objects had the same order, just like they would be executed in parallel, instead of waiting for the first chain to finish.

I finally found a solution with recurrency, but I doubt it's the best way of working with promises. Here's the code that works (+ needs some refactor and cleaning etc.), to show the rough idea:

function findOrCreateGroup(groupsQuery, index, callback) {
      var groupName = groupsQuery[index];

      Group.findOne({ 'name' : groupName }).then(function(group) {
        if (!group) {
           return Group.find().limit(1).sort('order DESC').then(function(foundGroups) {
               var maxOrder = 0;
               if (foundGroups.length > 0) {
                   maxOrder = foundGroups[0].order;
               }

               return Group.create({
                   'name' : groupName,
                   'order' : (maxOrder + 1)
               }).then(function(g) {
                 dbGroups[g.name] = g;

                 if (index + 1 < groupsQuery.length) {
                   findOrCreateGroup(groupsQuery, index + 1, callback);
                 } else {
                   callback();
                 }

                 return g;
               });
            });
        } else {

          dbGroups[group.name] = group;

          if (index + 1 < groupsQuery.length) {
            findOrCreateGroup(groupsQuery, index + 1, callback);
          } else {
            callback();
          }

          return group;
        }
      });
    }