Open In App

How to populate virtuals to a mongoose model using Node.js ?

Improve
Improve
Like Article
Like
Save
Share
Report

In Mongoose, the virtual is the property that is not stored in the database, they only exist logically, and you cannot query directly on the basis of this property. To know more about virtual refers to this article Mongoose Virtuals.

Populating Virtuals: 

In MongoDB, Population is the process of replacing the specified path in the document of one collection with the actual document from the other collection.

Mongoose also supports a population of virtual properties during their creation. Whenever we want our virtual property to refer to a model of any other collection we have to populate it so that it can contain the document(s) of the other collection.

Install Mongoose:

Step 1: You can visit the link Install mongoose to install the mongoose module. You can install this package by using this command.

npm install mongoose

Step 2: Now you can import the mongoose module in your file using:

const mongoose = require('mongoose');

Database: We have two collections users and posts in our database GFG. 

  • users: The users collection has two users User1 and User2.
  • posts: The posts collection is empty.

Initially users and posts collection in database

Implementation:

  1. Create a folder and add the file main.js.
  2. For populating virtual, we have to specify three necessary options:
    • ref: It contains the name of the model from which we want to populate the document.
    • localField: It is any field of the current collection.
    • foreignField: It is any field of the collection from which we want to populate the document.

Mongoose will populate those documents from the model given in ref, whose foreignField value will match with the localField value of the current collection.

Example: Now we will see how to populate virtuals to a mongoose model using Node.js.

main.js




// Requiring module
const mongoose = require('mongoose');
  
// Connecting to database
mongoose.connect('mongodb://localhost:27017/GFG',
    {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useFindAndModify: false
    });
  
// User Schema
const userSchema = new mongoose.Schema({
    username: String,
    email: String
})
  
// Post Schema
const postSchema = new mongoose.Schema({
    title: String,
    postedBy: mongoose.Schema.Types.ObjectId
})
  
// Creating and populating virtual property 'user' in postSchema
// will populate the documents from user collection if 
// their '_id' matches with the 'postedBy' of the post
postSchema.virtual('user', {
    ref: 'User',
    localField: 'postedBy', // Of post collection
    foreignField: '_id',    // Of user collection
    justOne: true
})
  
// Creating user and post models 
const User = mongoose.model('User', userSchema);
const Post = mongoose.model('Post', postSchema);
  
// Function to create a post by the user
const createPost = async (next) => {
    const user = await User.findOne({ _id: '60acfa48e82a52560c32ec0a' });
  
    const newPost = new Post({
        title: 'Post 1',
        postedBy: user._id
    })
  
    const postSaved = await newPost.save();
    console.log("post created");
  
    // The findPost will be called after the post is created
    next();
}
  
// Function to find the post and show the virtual property
const findPost = async () => {
    const post = await Post.findOne().populate('user');
    console.log(post.user);
}
  
// Creating the post then showing the virtual property on console
createPost(findPost);


Run main.js using the command:

node main.js

Output:  

Output after executing main.js

Explanation: Here we are finding User 1 by _id field and then creating a post whose postedBy field value will be the User 1 _id field value (hence the post is created by User 1). Whenever a post will be created, a virtual property ‘user’ will be created for the post which would be populated with the document of the User model whose _id field value matches with the postedBy value of the post.

Database: After creating a post with a populated virtual property user, we can see Post 1 in posts collection of our database. But here we cannot see the property user in the database because it’s a virtual property, and it doesn’t get stored in the database.

Posts collection after creating the post with populated virtual



Last Updated : 01 Jun, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads