Hi, in the process of learning Meteor, and I have followed the recommended learning path. I built the TODO application, I watched the excellent LevelUpTuts intermediate tutorial, and I’ve read the guide. Now the trouble is, I need to build an app where there are many to many relationships in my data, eg. a recipe has many ingredients that are also in many recipes. This is a pretty common scenario, so I wonder if there are any plans to include a detailed example of how to do this in the tutorials or documentation. Or did I simply miss something that’s already there.
Thank you.
1 Like
Thank you for this, but it doesn’t actually explain how to do this in Meteor, only in MongoDB. The trick is to ensure that the relationships are reactive in Meteor, right?
So I take it this is your way of saying, no this is not documented in Meteor yet?
(In MongoDB itself it is obviously trivial, and can be accomplished in several ways. )
I don’t really undearstand what are you asking.
Meteor is meteor. Mongo is mongo. Mongodb in meteor works same as in any other framework. You do not need to specify any reactive relathionships.
const Recipes = new Mongo.Collection('recipes')
const Ingridients = new Mongo.Collection('ingridients')
const ingridientId = Ingridients.findOne({ name: 'potato' })
const data = Recipes.find({ingridients: { $elemMatch: ingridientId } })
He means something what SQL calls a JOIN - that’s how you do relationsships in a relational database.
And currently, Meteor in conjunction with MongoDB doesn’t really offer a reactive solution natively. Sure, there’s $aggregate but that’s not reactive.
There are two ways to deal with this:
a) https://github.com/englue/meteor-publish-composite
b) use _.map
and _.foreach
and stuff.
That’s the drawback when using a non-relational database - this “document” stuff is a nice idea but doesn’t really hold up to reality in my opinion. Frankly, any time you have a relation between two models it’s a pain in the arse.
Why is it even an issue? According to my previous example if someone Recipes.insert{ ingridients: [‘potato’] } the “data” constant will be refreshed with one extra document inside. It is reactive, you do not need to do anything yourself.
Please correct me if i am wrong. I am little bit confused, last time i used sql db’s was like 2 years ago.
Easy: You have a list of comments and a list of users. And now you want the comments from each user.
In SQL that’s easy and one statement, it’s also one query:
SELECT Comments.comment_text, Users.username
FROM Comments
INNER JOIN USERS
ON Comments.user_id = Users.id;
Now, doing the same thing in Meteor and MongoDB is slightly more involved and also requires slightly more queries.
And that was a one-to-many relationship. Many-to-many gets even more fun!
Thank you rhywden, I will try your suggestion. Do you think an example of how to do this belongs in the official tutorial, given how common this data pattern is?
undeadlol1, why don’t you try it in Meteor and see if it works for you? Build a little mini app, where there’s one there’s many to many relationship between menus and ingredients. Perhaps you’ll be surprised, as I was.
I’m currently waiting on their Apollo stack to see whether they manage to solve this issue - the question is whether they’ll manage to extend the features or have to settle for the least common denonimator.
rhywden, would you say that this is one of the side effects of DDP architecture? You gain a lot, but it does add a layer of complexity for more “advanced” data relationships that would otherwise be somewhat trivial in a traditional request based web app?
By the way, the Apollo stack is ready, AFAIK. It’s on my todo list as well, but not for this scenario. I want to use it for multiple sources of read only data that I have in large quantities (100 million +)
This is really a side effect of MongoDB. The DDP architecture adds reactivity on top of MongoDB, but cannot address this limitation in any SQL-like way. MongoDB 3.2 adds the equivalent of a left outer join with the $lookup
operator when used in the aggregation pipeline, but this is not available in minimongo, so must be executed on the server using Meteor’s rawCollection
.
Reactive aggregations are possible with this package: https://atmospherejs.com/jcbernack/reactive-aggregate
1 Like
That package does not support JOINs so it’s basically unusable for the purpose outlined in this thread.
Getting back to my original question, does anyone believe that an example of how to do “many to many” belongs in a tutorial or guide, given how common a data pattern this is?
It is kind of a show stopper for me currently as a newbie. Although I’m trying to build a very simple app here, the lack of official guidance already has me stumped.
There must be other newbies in the same boat, as not everyone comes to this framework wanting to build simplistic apps from a data standpoint (eg. examples used in docs).
Sounds to be mostly like a Mongo problem you are having, and the mongo world already has a lot of advice on how to design things.
But there is
https://bulletproofmeteor.com/database-modeling/many-many-relationships
though its behind a paywall…
Well, that was a particular piece of useless advice.
Wanna know how to achieve what you want? Better pay up first!
You are probably best helped with the reywood:publish-composite package.
That only limits the amount of publications, though. You still have to pull in the data by hand in order to display it.
I mean, his example shows it: Instead of having one(1) query to find all the posts and their respective author, you now have n+1 queries - you query for all posts and then each post gets another query to find the author.
And as soon as your nesting is 2 or more levels deep, you get a lot of queries.
I don’t mind paying $39 for a tutorial, if I knew that a) it’s relatively recent, aka works for Meteor 1.3.2, and b) it doesn’t use IronRouter. But there is no date on the tutorial or indication of what packages it uses.
So teaching people about data is not really seen as the responsibility of Meteor documentation team? They focus a lot on whiz-bang UI features, but neglect the very reason for building applications in the first place, eg. data in data out. That can’t be right. I must have missed something in the docs.
This is the guide documentation on publishing relational data.
RobFallows, have you tried a many to many relationship using reywood:publish-composite?