In many ways meteor’s API encourages flat relational documents, however MongoDB is a non-relational data store. This conflict is, unfortunately, left as an exercise for the developer to solve.
The notion of schema structure and joins is an enormous topic to cover within a single answer, so I will attempt to be as succinct as possible.
Reasons why you should choose a relational model
Assume you have comment and post data. Consider what would happen if you embedded comments within your posts.
-
DDP operates on documents. All of the comments will be sent every time a new comment in the same post is added.
-
allow
anddeny
rules operate on documents. It may be unreasonable to expect that the same rules apply simultaneously to both posts and comments. -
Publications tend to make more sense in terms of collections. In the above scenario, we could not easily publish a list of comments independent of their posts.
-
Relational databases exist for good reasons. One of them is to avoid the multiple modification problem inherent in your second solution.
Reasons why you should choose an embedded model
- Joins are not supported natively by MongoDB, and there isn’t a core package to produce a reactive join.
Recommendations
Use your third solution. In my experience, the reasons for choosing a relational model far outweigh the restrictions imposed by the data store. Of course overcoming the lack of joins isn’t easy, but the pain is likely to be isolated to only a handful of publish functions. Here are some resources I’d highly recommend:
-
How to publish a many-to-many relationship on EventedMind. Chris covers your exact use case in detail, however he manually does the reactive join with observe callbacks, which I don’t recommend.
-
Reactive joins in meteor from the Discover Meteor Encyclopedia. This covers the basics of how and why one should do a reactive join.
-
The denormalization chapter from Discover Meteor. This covers many of the points I made above and also talks about when and how to denormalize some of your data.
-
You can use Publish with relations to join your data. Alternative packages include: smart publish, publish composite, and simple publish.
If you need more information beyond this, please comment below and I will update my answer.