Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Model for Representing Many to Many relationships with attributes in MongoDB

Tags:

What's the most 'mongo' way of representing many-to-many relationships that have attributes?

So for example:

Intro


MYSQL tables

people => firstName, lastName, ...

Movies => name, length ..

peopleMovies => movieId, personId, language, role

Solution 1


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.

Solution 2


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.

Solution 3


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.

like image 490
Maaz Avatar asked Aug 16 '14 22:08

Maaz


People also ask

Can MongoDB model many to many?

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.

Which model is used when there contains relationships between entities in MongoDB?

In general, use embedded data models when: you have "contains" relationships between entities.

Which model is used to describe reference relationships between documents in MongoDB?

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.


1 Answers

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 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.

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.

like image 80
David Weldon Avatar answered Oct 08 '22 16:10

David Weldon