Now for MongoDB referenced form – ‘normalized’ means ‘separated’. We need to separate documents, collections, and IDs.
Because Tutorials and Tags are all completely different document, the Tutorial need a way to know which Tags it has, so does a Tag that will know which Tutorials contain it. That’s why the IDs come in.
We’re gonna use Tutorials’ IDs for references on Tag document.
You can see that in the Tag document, we have an array where we stored the IDs of all the Tutorials so that when we request a Tag data, we can easily identify its Tutorials.
This type of referencing is called Child Referencing: the parent (Tag) references its children (Tutorials).
Nown how about Parent Referencing?
Each child document keeps a reference to the parent element.
We have Tutorials get references to its Tags’ Ids.
What we’ve just done is called Two-way Referencing where Tags and Tutorials are connected in both directions:
– In each Tag, we keep references to all Tutorials that are tagged.
– In each Tutorial, we also keep references to its Tags.
References or Embedding for MongoDB Many-to-Many Relationships
For Embedded Data Models, you can see that we can get all the data about Tutorial with its Tags (or Tag with its Tutorials) at the same time, our application will need few queries to the database. It will increase our performance.
But when the data become larger and larger, duplicates is inevitable.
And the risk is so serious in case we want to update document, even just a field, we have to find and update two place.
For example, if you want to change the name of tagA, you must have to change not only that Tag’s document but also find the Tutorial that contains the Tag, find that Tag exactly, then update the field. So terrible!
Hence, with Many-to-Many relationship, we always use Data References or Normalizing the data.
Mongoose Many-to-Many Relationship example
Setup Node.js App
Install mongoose with the command:
npm install mongoose
Create project structure like this:
src
models
Tag.js
Tutorial.js
index.js
server.js
package.json
Open server.js, we import mongoose and connect the app to MongoDB database.
In the code above, we set each item’s type of tutorials array to ObjectId and ref to Tutorial. Why we do it?
The Tutorial has only ObjectId in tutorials array. ref helps us get full fields of Tutorial when we call populate() method. I will show you how to do it later.
In models/Tutorial.js, define Tutorial with 3 fields: title, author, tags–
You can see that the tutorials/tags array field contains reference IDs.
This is the time to use populate() function to get full data. Let’s create two functions: