Mongoose Aggregate.prototype.unwind() API
Last Updated :
16 May, 2025
The Aggregate API.prototype.unwind() method of the Mongoose API is used to perform aggregation tasks. It allows us to break down complex and nested array or document fields in the MongoDB database or Schema. It returns a document object for every element present in the field. It deconstructs the array attribute to output a document object for every element in an array. This operation is particularly useful when you have embedded arrays or arrays within documents and need to "unwind" or flatten them into separate documents for further processing.
Syntax:
aggregate.unwind(field)
Parameters: This method accepts a single parameter as mentioned above
- field: The name of the field in your MongoDB collection that we want to deconstruct
Return Value:
The unwind()
method returns a new document for each element within the array field. It essentially creates a new document for each element in the array, preserving other fields from the original document.
Setting up Node.js application with Mongoose
To demonstrate the unwind() method in Mongoose, follow these steps
Step 1: Initialize a Node.js Application
Create a Node.js application using the following command:
npm init
Step 2: Install Mongoose
After creating the NodeJS application, Install the required module using the following command:
npm install mongoose
Project Structure: The project structure will look like this:
Database Structure: The database structure will look like this, the following documents are present in the collection.
Example 1: Using unwind()
to Flatten an Array of Marks
In this example, we have established a database connection using mongoose and defined model over studentSchema, having three columns or fields "studentId", "studentName", and "marks". At the end, we are using unwind() method on marks field to deconstruct the array and to get document for every element in array as output.
Filename: app.js
JavaScript
// Require mongoose module
const mongoose = require("mongoose");
// Set Up the Database connection
mongoose.connect("mongodb://localhost:27017/geeksforgeeks", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const studentSchema = new mongoose.Schema({
studentId: Number,
studentName: String,
marks: []
});
const Student = mongoose.model('Student', studentSchema);
const aggregate = Student.aggregate();
aggregate.unwind("$marks").exec((err, result) => {
if (err) {
console.log(err)
} else {
console.log(result)
}
})
Step to run the program: To run the application execute the below command from the root directory of the project:
node app.js
Output:
[
{
_id: new ObjectId("63862e73d408a33b4481fd05"),
studentId: 1,
studentName: "Aakash",
marks: 50,
__v: 0
},
{
_id: new ObjectId("63862e73d408a33b4481fd05"),
studentId: 1,
studentName: "Aakash",
marks: 65,
__v: 0
},
{
_id: new ObjectId("63862e73d408a33b4481fd05"),
studentId: 1,
studentName: "Aakash",
marks: 75,
__v: 0
},
{
_id: new ObjectId("63862e73d408a33b4481fd06"),
studentId: 2,
studentName: "Bhavesh",
marks: 80,
__v: 0
},
{
_id: new ObjectId("63862e73d408a33b4481fd06"),
studentId: 2,
studentName: "Bhavesh",
marks: 70,
__v: 0
},
{
_id: new ObjectId("63862e73d408a33b4481fd06"),
studentId: 2,
studentName: "Bhavesh",
marks: 90,
__v: 0
}
]
Example 2: Using unwind()
on Nested Array Fields (Cities)
In this example, we have established a database connection using mongoose and defined model over statesSchema, having three columns or fields "stateId", "stateName", and "city". At the end, we are using unwind() method on city field to deconstruct the array and to get document for every element in array as output. In the output we can see we are getting document object for each city that is present in city array at schema level.
Database Structure: The database structure will look like this, the following documents are present in the collection.
Filename: app.js
JavaScript
// Require mongoose module
const mongoose = require("mongoose");
// Set Up the Database connection
mongoose.connect("mongodb://localhost:27017/geeksforgeeks", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const statesSchema = new mongoose.Schema({
stateId: Number,
stateName: String,
city: []
});
const State = mongoose.model('State', statesSchema);
const aggregate = State.aggregate();
aggregate.unwind("$city").then(result => {
console.log(result)
}).catch(err => {
console.log(err)
})
Step to run the program: To run the application execute the below command from the root directory of the project:
node app.js
Output:
[
{
_id: new ObjectId("63863213430c4520ce61c186"),
stateId: 1,
stateName: 'Maharashtra',
city: 'Mumbai',
__v: 0
},
{
_id: new ObjectId("63863213430c4520ce61c186"),
stateId: 1,
stateName: 'Maharashtra',
city: 'Pune',
__v: 0
},
{
_id: new ObjectId("63863213430c4520ce61c186"),
stateId: 1,
stateName: 'Maharashtra',
city: 'Nagpur',
__v: 0
},
{
_id: new ObjectId("63863213430c4520ce61c187"),
stateId: 2,
stateName: 'Madhya Pradesh',
city: 'Bhopal',
__v: 0
},
{
_id: new ObjectId("63863213430c4520ce61c187"),
stateId: 2,
stateName: 'Madhya Pradesh',
city: 'Indore',
__v: 0
}
]
Important Points to Remember
- The
unwind()
method is ideal for flattening arrays into separate documents for further processing. - It can be applied to arrays of both primitive data types (like numbers or strings) and complex objects (such as subdocuments).
- If you use
unwind()
on a field that is not an array, Mongoose will throw an error.
Conclusion
The aggregate.unwind()
method is an essential tool for breaking down array fields in MongoDB. It’s especially helpful when you have embedded data that needs to be processed or analyzed individually, rather than as a single block. With Mongoose’s aggregation framework, handling complex documents becomes more efficient and flexible. By utilizing unwind()
, you can take advantage of MongoDB’s powerful aggregation pipeline to transform your data and build more efficient queries.