Populate in Mongoose: Node.js Comprehensive Guide

Populate is used to enhance one-to-many or many-to-one data relationships in MongoDB. The populate() method in Mongoose is used to replace the specified paths in a document with another document from other collections.

It lets you set the field’s value as the actual document that you are referring to. For instance, you are making a Reddit or Twitter clone. You have users on it and you want to integrate a commenting feature for them.  In order to identify who made the comment and perform actions on it, you will need some relationship between the user and their comments. This is where the populate() method in Mongoose comes in handy.

This tutorial will walk you through a perfect example of using populate() in Mongoose by creating a real-life application.

Mongoose populate() Method – Quick Step-by-Step Guide

To demonstrate the use of “populate()”, let’s create an application where we have two collections, one for farms and the other for the products sold by those farms.

Prerequisites

  • Beginner-level knowledge of NodeJS
  • Beginner-level knowledge of MongoDB
  • Beginner-level knowledge of Mongoose
  • Have installed Nodejs and MongoDB on your machine

Assuming that you meet the above prerequisites, we will now move on to creating the application.

Check: Installation, Setup, and Creating a Hello World Application in NodeJS

Below is the step-by-step process to create the application.

Setup Node.js Project

  • Open a terminal and create a new project directory and move into it using the following commands:
mkdir farmApp
 
cd farmApp
  • Initialize NPM inside the directory to install Mongoose:
npm init -y
  • Create an “index.js: file where we will write all the code for creating the application:
touch index.js
  • Install Mongoose using NPM:
npm i mongoose

Configuring Packages, Schemas, & Models

Now, open the project file inside a code editor and then open “index.js” to start writing the code.

  • First, we need to import the Mongoose module, which we can do using require() method:
const mongoose = require('mongoose');
 
const { Schema } = mongoose; // To get access to mongoose.Schema
  • Set up a connection to MongoDB using Mongoose:
mongoose.connect('mongodb://localhost:27017/farmStandTake2', { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => {
        console.log("MONGO CONNECTION OPEN!!!")
    })
    .catch(err => {
        console.log("OH NO MONGO CONNECTION ERROR!!!!")
        console.log(err)
    })

Here we have connected to the MongoDB local database using Mongoose, if you find any error, make sure that the MongoDB server is up & running in the background.

  • Create schemas & models for both farms and products, with references between them to enable population:

Farm schema and model

const farmSchema = new Schema({
    name: {
        type: String,
        required: [true, 'Farm must have a name!']
    },
    city: {
        type: String
    },
    email: {
        type: String,
        required: [true, 'Email required']
    },
    products: [
        {
            type: Schema.Types.ObjectId,
            ref: 'Product'
        }
    ]
});
 
const Farm = mongoose.model('Farm', farmSchema);

Product schema and model

const productSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    price: {
        type: Number,
        required: true,
        min: 0
    },
    category: {
        type: String,
        lowercase: true,
        enum: ['fruit', 'vegetable', 'dairy']
    },
    farm: {
        type: Schema.Types.ObjectId,
        ref: 'Farm'
    }
});
 
const Product = mongoose.model('Product', productSchema);

Inserting Documents

Now, to demonstrate the use of “populate”, we have to insert some documents of the model we just created, we have a separate tuitorial on inserting data in MongoDB if you want to know about it.

Let us take a look at a farm document that we have inserted:

{
  products: 6170854b496fcd1b541f5b1a,
  _id: 6170847b496fcd1b541f5b19,
  name: "Giovanni's Wheat Fields",
  city: 'Marzamemi, Sicily',
  email: '[email protected]',
  __v: 0
}

And, this is what our product looks like:

{
  _id: 6170854b496fcd1b541f5b1a,
  name: 'Whole Wheat Grains',
  price: 1,
  category: 'vegetable',
  farm: 6170847b496fcd1b541f5b19,
  __v: 0
}

Now we don’t want to show them individually rather we want users to see which farm is selling which product and which product is associated with which farm.

We can use Mongoose populate() method to achieve that.

Using Mongoose populate() Method

For a product, we want to populate the name and id of the farm associated with it. We can do this by using the populate() method.

Product.find()
.populate('farm', 'name')
.then(product=>console.log(product))
.catch(error=>console.log(error));

Here we have passed two arguments ‘farm’ and ‘name’ which specify that the ‘farm’ field of ‘product’ documents will be populated with the ‘name’ field of referenced ‘form’ documents.

For the farm, we will populate the entire products documents associated with it:

Farm.find()
.populate('products')
.then(farm=>console.log(farm))
.catch(error=>console.log(error));

Now, let’s check what our farm and products look like after using populate:

Product

{
  _id: 6170854b496fcd1b541f5b1a,
  name: 'Whole Wheat Grains',
  price: 1,
  category: 'vegetable',
  farm: { _id: 6170847b496fcd1b541f5b19, name: "Giovanni's Wheat Fields" },
  __v: 0
}

Farm

{
  products: [
    {
      _id: 6170854b496fcd1b541f5b1a,
      name: 'Whole Wheat Grains',
      price: 1,
      category: 'vegetable',
      farm: 6170847b496fcd1b541f5b19,
      __v: 0
    }
  ],
  _id: 6170847b496fcd1b541f5b19,
  name: "Giovanni's Wheat Fields",
  city: 'Marzamemi, Sicily',
  email: '[email protected]',
  __v: 1
}

In the above output, see the fields are populated, this is how we have successfully demonstrated the Mongoose populate().

Summary

Populate in MongoDB is helpful when selecting related data from multiple collections and combining it into a single document. The populate() method allows you to replace a field of one collection with any other document or document’s field from another collection based on the reference field. Hope this tutorial helps you to understand this concept.

Also Read: Explaining the Ultimate Difference Between MongoDB vs Mongoose

Reference

https://mongoosejs.com/docs/populate.html

Aneesha S
Aneesha S
Articles: 174