Can a "Foreign Key" be implemented in Mongo?


#1

I want to implement a foreign key of some sort

var ClassSchema = new SimpleSchema({
  name: { type: String },
  number: { type: String },
  enrolled: { type: [ForeignKey('students')] }
});

Utlimately, the result of a Profile.find() would be like this:

{
  _id: "someid",
  number: "CS323",
  enrolled: [{
    _id: "someotherid",
    name: "Ben"
  }, {
    _id: "evenanotherid",
    name: "Jessica"
  }]
}

I’m just wondering, has anyone come across this kind of problem before? I feel like it must be very common and happen frequently and I am looking for possible solutions others have used.


Node supports DBRef, does mongo?
#2

I use the collection-helpers for situations like this.
https://atmospherejs.com/dburles/collection-helpers

There are other packages out there too to help you with joins:
https://atmospherejs.com/?q=join


#3

Joins defined on the schema is not available yet, though is one of the future goals of the project.

Currently, there are two things you need to take care of:

  • Publish (from the server to the client) the related data along with the parent data
  • Get to the child data from the parent data

and do these reactively.

While this is perfectly possible using Meteor’s built in tools (publish, subscribe, observeChanges, livedata, minimongo), the community have stepped up to develop quite powerful packages that provide you with easy, declarative solutions.

The publish part of the problem has been addressed by many different packages (do a search for keywords like publish and relation on atmoshpere) and my personal preference is with either one of:

I should mention that there are a lot more very sophisticated packages out there solving the very same problem. These two are my personal preference and I often find myself using the first and flirting with the second.

The second part of the problem is solved with:

which is kind of the defacto standard in the community.

All these packages have pretty good documentation and nice examples, so if you take a couple of hours of your time to read the docs and reproduce the examples - http://www.meteorpad.com is a great place to play around with meteor code - I’m sure you’ll be off on your feet.


#4

I’ve found a way to kind of do it with AutoForm, thought I’d leave it here for now if anyone needs it

var StudentSchema = new SimpleSchema({
  // ...
  classes: {
    type: [String],
    autoform: {
      options: function() {
        return Classes.find().map(function(doc) {
          return { label: doc.name, value: doc._id };
        })
      }
    }
  }
});

pairing this with @serkandurusoy’s suggestion makes for a pretty convenient way to fetch a document.

Students.helpers({
  classes: function() {
    return _.each(this.classes, function(docId) {
      return Classes.findOne(docId);
    })
  }
});

So my original json could look like

{
  name: Cats McMeows,
  classes: ["12345", "56789"]
}

then you can use the query to get better results when you actually need them

Students.findOne().classes();
[{
  name: "Particle Physics"
}, {
  name: "Playing with Yarn"
}]