How to return grandchildren properties from a query with Mongoose

Mongoose is a Node.js-based object modeling tool for MongoDB to develop specific schemas for your application.

MongoDB is a NoSQL database that uses JSONJavaScript Object Notation-like documents to store data, so there are subtle differences in data storage and retrieval compared to relational databases.

The relationship between Mongoose, Node.js, and MongoDB is illustrated below:

Mongoose schemas allow you to create nested objects stored in the database as a collection of subdocuments. To obtain the properties of a nested object, a few extra steps need to be performed on the original query.

To use Mongoose, you will first need to install a few dependencies through the following commands:

npm init -y
npm install express mongoose

Next, you will need to install MongoDB. You can use the following link to find and install the relevant version for your operating system.

The code below creates a model with grandchild properties in Mongoose:

const mongoose = require("mongoose");
// connect to local mongoDB instance
mongoose.connect("mongodb://localhost:27017/test", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// model for a person's grandchild
const grandChildSchema = mongoose.Schema({
name: String,
age: Number,
});
// model for a person's child
const childSchema = mongoose.Schema({
name: String,
age: Number,
grandchild : grandChildSchema,
});
// model for a person
const personSchema = mongoose.Schema({
name: String,
age: Number,
child: childSchema,
});
const person = mongoose.model('person', personSchema);
// intialize and save objects to database
let person_object = new person({name : "Alice", age: 60, child : { name : "Bob", age : 30, grandchild : { name : "Peter", age: 9}}});
person_object.save((err, res) => {
if (err) return console.error(err);
console.log("Saved");
});
person_object = new person({name : "Jack", age: 52, child : { name : "Jane", age : 29, grandchild : { name : "Jason", age: 4}}});
person_object.save((err, res) => {
if (err) return console.error(err);
console.log("Saved");
});
person_object = new person({name : "Adam", age: 80, child : { name : "Carl", age : 55, grandchild : { name : "Mary", age: 35}}});
person_object.save((err, res) => {
if (err) return console.error(err);
console.log("Saved");
});

The code above contains three different schemas that represent a person, their child, and their grandchild, respectively. Each model has an associated name and age for its instances.

person_object serves as a nested object that holds all the relevant information needed to represent a person as per the defined model. The save() method is used to store all the objects in the database.

Once the objects have been stored in the database, you can create queries to retrieve the data. The code below shows how you can extract the grandchild properties for each stored object:

// list of person names
const person_names = ["Alice", "Jack", "Adam"];
// looping over each person
for (let index = 0; index < person_names.length; index++)
{
// find person with the matching name
person.findOne({ name: person_names[index] }, (err, res) => {
// Check for errors while reading data
if(err)
{
return console.error(err);
}
// Print the grandchildren properties of result
const grandchild_name = res.child.grandchild.name;
const grandchild_age = res.child.grandchild.age;
console.log(`${person_names[index]}\'s granchild ${grandchild_name} is ${grandchild_age} years old.`);
});
}

First, the names to be searched for are stored in the array person_names. A for-loop proceeds to iterate over each name, and the findOne() method is used to read the document from the database whose name matches the one being searched for.

If an error arises during the read operation, the specifics of the error are returned; otherwise, the name and age of the grandchild object are displayed, as shown below:

widget

Note: To explore Mongoose further, you can check the documentation.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved