Using reference to documents and retrieving them later. Mongoose

Mongoose, Express how to use Model.Populate and create references

Using reference to documents and retrieving them later. Mongoose

Photo by Alazar Kassahun on Unsplash

I am a junior developer, who is learning A LOT of new things constantly, and from time to time, I feel like I would really like to share, things that I found interesting throughout my learning journey. I would like to thank you for joining me on my journey, and I hope you can find something useful and deepen your understanding also!

So, what is ref, and what is the point of it ? To begin, ref is a reference to a document within another collection. For example, in my project, I am have a City model, and within the model, I have a stories, and every city can have many stories. Now, with the help of ref we can actually create a reference inside City model, to the each story, that is associated with the city.

First of all, let's take a look at our City schema.

models/cityModel.js

const citySchema = new mongoose.Schema({
  name: String,
  stories: [{ type: mongoose.Schema.Types.ObjectId, ref: "Story" }],
})

Notice how our citySchema has an array of objects called stories, and within that array, it says { type: mongoose.Schema.Types.ObjectId, ref: "Story" } , this just defines that we want to save the ObjectId and a reference path to the "Story". Now in our case, if we would see, how our stories would look, within the cityModel, if we had some data, you would see something like this: Stories with IDs

Inside our stories array, there are two(mock in our case) IDs. Those are the IDs of the Stories that were added to our citySchema. So now, that we have our IDs, lets say we want to access all of our stories for that particular city. To do that, we need to use Model.populate(), what will populate do, is retrieve those stories and give us back a new City with the data that we wanted. This is how we would use populate()

controllers/cityController.js

  City.findOne({ name: req.params.cityName })
    .populate("stories")
    .exec((err, stories) => {
      res.status(200).json({ stories });
    });

We want to retrieve the particular City, and all the stories that the city holds, however, we want the STORIES, not just the ObjectId to the stories. So we first findOne city that we want to get data from, and call .populate("which property to populate/work with") it then replaces(or should I say, populates) our stories with the referenced documents Ids. We then use .exec which just runs once, to return our stories. And just like that, now we are getting our City with the Stories, instead of just IDs.

Populated data

The whole code is available here : Github URL