(part 4) (5 mins reading)(MongoDB) Primary modeling patterns and Relationships
Ezat Elzalouy
Software Engineer @ Mismar | Javascript | Typescript | SQL - NOSQL | 5 years exp
From this article onwards, we will use this updated?mind map?as a measure of our progress in all future articles. I have made improvements to the mind map, and we will now be using it consistently going forward.
Relationships
In any database you will build, you find yourself selecting a relationship to build your related data like One-to-Many, One-to-One, or Many-to-Many. So in mongoDb To model relationships, there are three main approaches: Embedding, Referencing, and a Hypred approach that combines both and we talked about the difference between them in the previous articles. if you don't know the difference just click here.
It's not a Rule for matching between the approach and the relationship but it's better in most of the Database domains we see in our systems.
so Embedding is best suited for one-to-one and one-to-many relationships, where the related data is small and doesn't change frequently.
But Referencing involves storing data references to related data in separate documents, which are then quired separately. This approach is best suited for many-to-many relationships. Where the related data is large and frequently changing.
you can read this article to know more about where to use Embedding or Referencing, Where this article builds upon the previous articles.
One-to-One
Let's say we have these two domains
// user documen
{
_id: "joe",
name: "Joe Bookreader"
}
// address document
{
patron_id: "joe", // reference to patron document
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
领英推荐
{
? "_id": 1,
? "title": "The Arrival of a Train",
? "year": 1896,
? "runtime": 1,
? "released": ISODate("01-25-1896"),
? "poster": "https://ia.media-imdb.com/images/M/MV5BMjEyNDk5MDYzOV5BMl5BanBnXkFtZTgwNjIxMTEwMzE@._V1_SX300.jpg",
? "plot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, ...",
? "fullplot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, the line dissolves. The doors of the railway-cars open, and people on the platform help passengers to get off.",
? "lastupdated": ISODate("2015-08-15T10:06:53"),
? "type": "movie",
? "directors": [ "Auguste Lumière", "Louis Lumière" ],
? "imdb": {
? ? "rating": 7.3,
? ? "votes": 5043,
? ? "id": 12
? },
? "countries": [ "France" ],
? "genres": [ "Documentary", "Short" ],
? "tomatoes": {
? ? "viewer": {
? ? ? "rating": 3.7,
? ? ? "numReviews": 59
? ? },
? ? "lastUpdated": ISODate("2020-01-09T00:02:53")
? }
}
What is the problem?
In the first Data model, while our application needs to retrieve all the data of the user at one query, we could use the One-to-one pattern with the Embedded document pattern. While the address data is frequently retrieved with user information. Then Referencing approach here can cause un-useful multiple queries to resolve the reference. On the other hand, using the Embedding pattern will make the reading queries faster and will achieve the application demands.
But second data model, The application demands are different and we need to show only an overview of the movie. The Embedded pattern here can cause a reading issue. This unnecessary data can cause extra load on your server and slow down read operations and let's imagine you have millions of Movies documents.?So you can use SubSet to store the most accessed data in a separate collection.
The subset pattern implementation depends on separating the collection into two collections with a One-to-One relationship, the first one for the frequently accessed data and the second one for unnecessary data:
{
"_id": 1,
"title": "The Arrival of a Train",
"year": 1896,
"runtime": 1,
"released": ISODate("1896-01-25"),
"type": "movie",
"directors": [ "Auguste Lumière", "Louis Lumière" ],
"countries": [ "France" ],
"genres": [ "Documentary", "Short" ],
}
{
"_id": 156,
"movie_id": 1, // reference to the movie collection
"poster": "https://ia.media-imdb.com/images/M/MV5BMjEyNDk5MDYzOV5BMl5BanBnXkFtZTgwNjIxMTEwMzE@._V1_SX300.jpg",
"plot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, ...",
"fullplot": "A group of people are standing in a straight line along the platform of a railway station, waiting for a train, which is seen coming at some distance. When the train stops at the platform, the line dissolves. The doors of the railway-cars open, and people on the platform help passengers to get off.",
"lastupdated": ISODate("2015-08-15T10:06:53"),
"imdb": {
"rating": 7.3,
"votes": 5043,
"id": 12
},
"tomatoes": {
"viewer": {
"rating": 3.7,
"numReviews": 59
},
"lastUpdated": ISODate("2020-01-29T00:02:53")
}
Using smaller documents containing more frequently-accessed data reduces the overall size of the working set. These smaller documents result in improved reading performance and make more memory available for the application.