Sunday, February 21, 2016

MongoDB - Working with Relationships

Relationships in MongoDB represent how various documents are logically related to each other. Relationships can be modeled via Embedded andReferencedapproaches. Such relationships can be either 1:1, 1: N, N: 1 or N: N.


In previous posts we have seen Data modelling in MongoDB and we have seen how we can perform data modelling using Referencing of Documents or Embedding document in MongoDB.

In this post we will be discussing about relationship between documents and relationship in MongoDB. Like we maintain relationship in Traditional Databases  one-to-one, one-to-many, many-to-many, the same one-to-one, one-to-many, many-to-many we will see how these can be achieved in MongoDB.

There are three types of Relationship:
  • One-to-One (1:1) Relationship
  • One-to-Many (1:N) Relationship
  • One-to-One (M:N) Relationship

The understanding of these relationships, mappings between documents, collections is important to learn to make Design and Develop Application in MongoDB.

One-to-One (1:1) Relationship

In Relationship database we map one table to another table with the help of foreign key, then we do the mapping and sometimes we keep the data in the same table and we do the one to one mapping. It all depend on how efficient you want to design your database.


In MongoDB we implement these Relationship using two strategies, one is Embedding and other is Linking ( Referencing).
Suppose I want to achieve one to one relation in MongoDB. I have a Customer document in MongoDB and I have a same Address document for the same customer, and I want to achieve one to one relationship between customer and Address document.

Suppose Customer information is as:
{
  name: "Anil Sharma"
  business: "Telecom"
}

Address information in other document is as:
{
  street:"10 Andheri East"
  city: "Mumbai"
  state: "Maharashtra"
}

Now there are two ways by which these information can be stored in MongoDB. First is Embedding these two document in one document and another one is to have two document and I can reference one in another via foreign key strategy.

Handing one-to-one using Embedding Document:
The above situation can be handled by embedding the document into another document as:
{
  name: "Anil Sharma"
  business: "Telecom"

address:{
  street:"10 Andheri East"
  city: "Mumbai"
  state: "Maharashtra"
       }
}

Address document has been embedded inside Customer document. This way we can achieve one-to-one mapping, one customer one address. 

Handing one-to-one using Referencing Document:
Suppose we have customer document as:
{
   _id: 101,
   name: "Anil Sharma"
  business: "Telecom"
}

Another, Address document is as:
{
  street:"10 Andheri East"
  city: "Mumbai"
  state: "Maharashtra"
}

Along with street, city, state information in Address document, which we had in previous made address document, we have one more column/field or key-value pair cust_id and that customer id is referring to this id of this customer field. Customer and Address document are now getting together with this id field. In this way we can refer one document in another. This way we can refer one-to-one relationship in MongoDB.  

One-to-Many (1:N) Relationship:

Suppose I have a Student document which is having information about Student details. Another document with Subjects, which will contain information on which student has which subjects. One student can have many subjects.

So We need to achieve one-to-many relationship. Student ---- (1:N)---- Subjects.

Student document has following details:
{
name:"Anil Sharma"
school:"DPS"
}

Subjects Document is as:
{
  Teacher: "John Carry"
  Subject:"Science"
},
{
  Teacher: "Mark T"
  Subject:"Biology"

}  

We need to maintain one to many relationship between these two documents using Embedding and Referencing methods.

Handing one-to-many using Embedding Document:
As we did in one-to-one mapping, again we will have subjects document inside Student document.

We will write Student document with field "name" and "school" as previous document, now we will have another field "subjects" array and this subject array will contain document for each subject.
{
  name:"Anil Sharma",
  school: "DPS",
  subjects:[{Teacher:"John Carry"
    Subject: "Science"
            },{
    Teacher: "Mark T"
    subject:"Biology"
            }]

This way one student can have many subjects. If we want to subject information with student it can be achieved in a single query.

Handing one-to-many using Referencing:
Now we will try to achieve one-to-many relationship using Referencing. Suppose we have student document with _id, name and school fields as:
{
   _id:101,
  name:"Anil Sharma",
  school:"DPS"
}

Now I have subject document with fields, Teacher name and Subject name along with student ID (std_id) field. 

  std_id:101,
  Teacher: "Mark T"
  subject:"Biology"
}

{
  std_id:101,
  Teacher:"John Carry",
  Subject: "Science"
}

This way we will create subject document for each student. We are achieving one-to-many relationship, one student is having two or more subjects. This is like foreign key relationship.


Another example of one-to-many relationship, consider the following example that maps patron and multiple address relationships. The example illustrates the advantage of embedding over referencing if you need to view many data entities in context of another. In this one-to-many relationship between patron and address data, the patron has multiple address entities.
In the normalized data model, the address documents contain a reference to the patron document.
{
   _id: "joe",
   name: "Joe Bookreader"
}

{
   patron_id: "joe",
   street: "123 Fake Street",
   city: "Faketon",
   state: "MA",
   zip: "12345"
}

{
   patron_id: "joe",
   street: "1 Some Other Street",
   city: "Boston",
   state: "MA",
   zip: "12345"
}
If your application frequently retrieves the address data with the name information, then your application needs to issue multiple queries to resolve the references. A more optimal schema would be to embed theaddress data entities in the patron data, as in the following document:
{
   _id: "joe",
   name: "Joe Bookreader",
   addresses: [
                {
                  street: "123 Fake Street",
                  city: "Faketon",
                  state: "MA",
                  zip: "12345"
                },
                {
                  street: "1 Some Other Street",
                  city: "Boston",
                  state: "MA",
                  zip: "12345"
                }
              ]
 }
With the embedded data model, your application can retrieve the complete patron information with one query.

Many-To-Many (M:N) Relationship 

 In Relation Database systems like oracle, mysql, we achieve this using joins. We join two or more tables to achieve many-to-many relationship.

Suppose we have Author document and Article document. One Author can write multiple article and one Article can be written by one or more Authors. So there is a Many to Many relationship between Author and Article.  
Author-----M:N:---- Article

Two way Embedding for Handling many-to-many relationship:

Suppose there are two authors who have written articles. "Author" document is as:
{ id:1,
  name: "Anil Sharma",
  articles:[1,2]
}
{ id:2,
  name: "John K",
  articles:[2]
}

Article 2 is common here in both the Author.  

Similarly Article Document. It has id, title, categories and authors as:
{
  id: 1,
  title: "MongoDB Design",
  categories:["Nosql"],
  authors:[1,2]
}
{
  id:2,
  title:"RDBMS Intro",
  categories:["Relational Database"],
  authors:[2]
}

This is two way embedding. We are embedding Articles in author document and embedding Authors in Article document. One Author has many article and one article has many author. So in Author document we are referring Article, and in Article document we are referring Authors.

No comments:

Post a Comment

Mongodb explain() Query Analyzer and it's Verbosity

First creating 1 million documents: > for(i=0; i<100; i++) { for(j=0; j<100; j++) {x = []; for(k=0; k<100; k++) { x.push({a:...