Today's Overview:
Hello everyone❤❤❤! Hope you're all doing well. Yesterday, my friend and I set up a public Git repository and started working on a practice project together. Today, I kicked off my coding journey by reviewing my front-end skills and practicing on the project we started. I also learned a bit about managing a project within a team. Later, I played a few matches of Valorant and won them of course 😎, then went on to explore some new topics. and here I what I learned.
Yesterday, I began learning about the MongoDB Aggregation Framework, though I didn’t manage to finish it all. I covered some of what I learned in my blog—here’s the link if you’re interested:
. That’s where I kicked things off!Mongodb Aggregation operators
$group
, $unwind
, $bucket
Example:
Imagine we have a sales
collection with the following documents:
[
{ "_id": 1, "product": "laptop", "category": "electronics", "quantity": 2, "price": 800, "storeLocation": "New York", "date": "2024-11-01" },
{ "_id": 2, "product": "smartphone", "category": "electronics", "quantity": 5, "price": 500, "storeLocation": "Los Angeles", "date": "2024-11-02" },
{ "_id": 3, "product": "laptop", "category": "electronics", "quantity": 1, "price": 800, "storeLocation": "Chicago", "date": "2024-11-03" },
{ "_id": 4, "product": "desk", "category": "furniture", "quantity": 3, "price": 150, "storeLocation": "New York", "date": "2024-11-04" },
{ "_id": 5, "product": "chair", "category": "furniture", "quantity": 10, "price": 75, "storeLocation": "Los Angeles", "date": "2024-11-05" }
]
$group
The $group
Groups documents by a specified field and can perform aggregate operations. if you use {group:{_id: null}}
all the document will be shown in this group.
$group
aggregation operators
$count
Calculates the number of documents in the given group.
$max
Displays the maximum value of a document’s field in the collection.
$min
Displays the minimum value of a document’s field in the collection.
$avg
Displays the average value of a document’s field in the collection.
$sum
Sums up the specified values of all documents in the collection.
$push
Adds extra values to the array of the resulting document. if you want to get all data of the document you can use{$push: "$$ROOT" }
db.sales.aggregate([
{ $group: { _id: "$product", totalQuantity: { $sum: "$quantity" } } }
])
//output
[
{ "_id": "laptop", "totalQuantity": 3 },
{ "_id": "smartphone", "totalQuantity": 5 },
{ "_id": "desk", "totalQuantity": 3 },
{ "_id": "chair", "totalQuantity": 10 }
]
$unwind
The $unwind
stage in MongoDB is used to "deconstruct" an array field from the documents in a collection, creating a separate document for each element in the array.
//data
[
{ "_id": 1, "name": "Alice", "hobbies": ["reading", "swimming", "cycling"] },
{ "_id": 2, "name": "Bob", "hobbies": ["painting", "hiking"] },
{ "_id": 3, "name": "Charlie", "hobbies": [] }
]
db.people.aggregate([
{
$unwind: {
path: "$hobbies",
preserveNullAndEmptyArrays: true
}
}
])
//output
[
{ "_id": 1, "name": "Alice", "hobbies": "reading" },
{ "_id": 1, "name": "Alice", "hobbies": "swimming" },
{ "_id": 1, "name": "Alice", "hobbies": "cycling" },
{ "_id": 2, "name": "Bob", "hobbies": "painting" },
{ "_id": 2, "name": "Bob", "hobbies": "hiking" },
{ "_id": 3, "name": "Charlie", "hobbies": null }
]
Charlie’s document is included with hobbies as null because of preserveNullAndEmptyArrays: true
.
$bucket
The $bucket
stage in MongoDB’s aggregation pipeline groups documents into buckets based on specified ranges.
//data
[
{ "_id": 1, "name": "Laptop", "price": 1200 },
{ "_id": 2, "name": "Smartphone", "price": 600 },
{ "_id": 3, "name": "Tablet", "price": 300 },
{ "_id": 4, "name": "Monitor", "price": 200 },
{ "_id": 5, "name": "Keyboard", "price": 50 }
]
db.products.aggregate([
{
$bucket: {
groupBy: "$price", // Field to group by
boundaries: [0, 200, 500, 1000, 2000], // Define bucket ranges
default: "Other",
output: {
count: { $sum: 1 },
products: { $push: "$name" }
}
}
}
])
//output
[
{ "_id": 0, "count": 2, "products": ["Keyboard", "Monitor"] },
{ "_id": 200, "count": 1, "products": ["Tablet"] },
{ "_id": 500, "count": 1, "products": ["Smartphone"] },
{ "_id": 1000, "count": 1, "products": ["Laptop"] }
]
groupBy:
Specifies the field to group by, in this case, price.
boundaries:
Defines the ranges for each bucket. For instance, [0, 200) will group products with a price between 0 (inclusive) and 200 (exclusive).
default:
Specifies the bucket for any values that don’t fall within defined boundaries.
output:
Specifies fields to include in each bucket. Here, we count the number of products in each bucket and list product names.
$sort
$sort
Sorts documents by a specified field.
db.products.aggregate([
{ $sort: { price: -1 } }
])
//output
[
{ "_id": 1, "name": "Laptop", "price": 1200 },
{ "_id": 2, "name": "Smartphone", "price": 600 },
{ "_id": 3, "name": "Tablet", "price": 300 },
{ "_id": 4, "name": "Monitor", "price": 200 },
{ "_id": 5, "name": "Keyboard", "price": 50 }
]
$limit
$limit:
Limits the number of documents returned by the pipeline.
db.products.aggregate([
{ $limit: 2 }
])
//output
[
{ "_id": 1, "name": "Laptop", "price": 1200 },
{ "_id": 2, "name": "Smartphone", "price": 600 },
]
$facet
The $facet
stage in MongoDB’s aggregation pipeline allows you to run multiple aggregation pipelines on the same dataset in a single stage, returning separate results for each pipeline.
db.products.aggregate([
{
$facet: {
topExpensiveProducts: [
{ $sort: { price: -1 } },
{ $limit: 3 }
],
avgPriceByCategory: [
{ $group: { _id: "$category", avgPrice: { $avg: "$price" } } }
]
}
}
])
//output
[
{
"topExpensiveProducts": [
{ "_id": 1, "name": "Laptop", "category": "electronics", "price": 1200, "quantity": 30 },
{ "_id": 2, "name": "Smartphone", "category": "electronics", "price": 600, "quantity": 50 },
{ "_id": 3, "name": "Tablet", "category": "electronics", "price": 300, "quantity": 70 }
],
"avgPriceByCategory": [
{ "_id": "electronics", "avgPrice": 700 },
{ "_id": "furniture", "avgPrice": 150 }
],
}
]
$lookup
The $lookup
stage allows us to join the two collections
Let’s say we have two collections: orders and customers.
//order collection
[
{ "_id": 1, "customerId": 101, "product": "Laptop", "total": 1200 },
{ "_id": 2, "customerId": 102, "product": "Smartphone", "total": 600 },
]
//customers collection
[
{ "_id": 101, "name": "Alice", "location": "New York" },
{ "_id": 102, "name": "Bob", "location": "Los Angeles" },
]
db.orders.aggregate([
{
$lookup: {
from: "customers",
localField: "customerId",
foreignField: "_id",
as: "customerInfo"
}
}
])
//output
[
{
"_id": 1,
"customerId": 101,
"product": "Laptop",
"total": 1200,
"customerInfo": [
{ "_id": 101, "name": "Alice", "location": "New York" }
]
},
{
"_id": 2,
"customerId": 102,
"product": "Smartphone",
"total": 600,
"customerInfo": [
{ "_id": 102, "name": "Bob", "location": "Los Angeles" }
]
}
]
from:
Specifies the collection to join with (customers).
localField:
Specifies the field in the current collection (orders) that you want to match (customerId).
foreignField:
Specifies the field in the customers collection that corresponds to localField (_id).
as:
Specifies the name of the new field where matched documents from customers will be added as an array (customerInfo).
Indexes in Mongodb
In MongoDB, indexes improve query performance by allowing the database to quickly locate documents that match a specific search criterion. You can create indexes on fields that you frequently query.
db.collection.createIndex({ field: order })
field:
The field you want to index.
order:
1 for ascending order or -1 for descending order.
Indexes should be created thoughtfully, as each index requires storage space and may affect write performance.
To delete an index
db.users.dropIndex("index_name")
Top comments (0)