What's the most 'mongo' way of representing many-to-many relationships that have attributes?
So for example:
MYSQL tables
people
=> firstName, lastName, ...
Movies
=> name, length ..
peopleMovies
=> movieId, personId, language, role
Embed people into movies...?
In MongoDB I understand it's good to denormalize and embed
but I don't want to embed
people into movies, it just doesn't logically make any sense. Because people don't necessarily only have to belongs to movies.
People
and Movies
will be two separate collections.
People
=> embed [{movieId: 12, personId: 1, language: "English", role: "Main"} ...]
Movies
=> embed [{movieId: 12, personId: 1, language: "English", role: "Main"} ...]
The issue with this solution is that when we want to update a person's role
for a specific movie
we'll need to run two update queries to ensure data is in sync in both collections.
We can also do something much more relational like and end up with three collections
People
=> firstName, lastName, ...
Movies
=> name, length ..
Castings
=> movieId, personId, language, role
The issue with this is that because of the lack of a join statement in MongoDB, it would take 3 queries
to go from people -> movies and vice versa.
Here is my question, what are some other ways to model something like this in MongoDB
and in a more NoSQL
way. In terms of the solutions provided, which one would be the best in terms of performance and convention in mongo.
A Many-to-Many relationship (N:M) As there is no single command to implement a many-to-many relationship in a relational database, it is more difficult than a one-to-many relationship. The same is true when using mongoDB to implement them. In fact, you can't use a command to create any type of relationship in MongoDB.
In general, use embedded data models when: you have "contains" relationships between entities.
1. Which of the following relationship uses references to describe documents between connected data? Explanation: One-to-Many Relationships with document references presents a data model that uses references to describe one-to-many relationships between documents.
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.
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
and deny
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With