Poyraz Yilmaz
Poyraz Yilmaz

Reputation: 5857

Meteorjs - What is the proper way to join collections on backend

I am very new to meteor.js and try to build an application with it. This time I wanted to try it over MEAN stack but at this point I am struggled to understand how to join two collection on server side...

I want very identical behaviour like mongodb populate to fetch some properties of inner document.

Let me tell you about my collection it is something like this

{
  name: 'Name',
  lastName: 'LastName',
  anotherObject: '_id of another object'
}

and another object has some fields

{
  neededField1: 'asd',
  neededField2: 'zxc',
  notNeededField: 'qwe'
}

So whenever I made a REST call to retrieve the first object I want it contains only neededFields of inner object so I need join them at backend but I cannot find a proper way to do it.

So far while searching it I saw some packages here is the list

  1. Meteor Collections Helper
  2. Publish with Relations
  3. Reactive joins in Meteor (article)
  4. Joins in Meteor.js (article)
  5. Meteor Publish Composite

Upvotes: 1

Views: 484

Answers (1)

Michel Floyd
Michel Floyd

Reputation: 20226

You will find the reywood:publish-composite useful for "joining" related collections even though SQL-like joins are not really practical in Mongo and Meteor. What you'll end up with is the appropriate documents and fields from each collection.

Using myCollection and otherCollection as pseudonyms for your two collections:

Meteor.publishComposite('pseudoJoin', {
    find: function() {
        return myCollection.find();
    },
    children: [
        {
            find: function(doc) {
                return otherCollection.find(
                    { _id: post.anotherObject },
                    { fields: { neededField1: 1, neededField2: 1 } });
            }
        }
    ]
});

Note that the _id field of the otherCollection will be included automatically even though it isn't in the list of fields.

Update based on comments

Since you're only looking to return data to a REST call you don't have to worry about cursors or reactivity.

var myArray = myCollection.find().fetch();
var myOtherObject = {};
var joinedArray = myArray.map(function(el){
  myOtherObject = otherCollection.findOne({ _id: el.anotherObject });
  return {
    _id: el._id,
    name: el.name,
    lastName: el.lastName,
    neededField1: myOtherObject.neededField1,
    neededField2: myOtherObject.neededField2
  }
});
console.log(joinedArray); // These should be the droids you're looking for

This is based on a 1:1 relation. If there are many related objects then you have to repeat the parent object to the number of children.

Upvotes: 1

Related Questions