Aggregation lồng: $group + $sum đếm số lượng sản phẩm theo ProductName
Sử dụng $group để gom theo ProductName, tính tổng ActualAmount, ProductQuantity, và đếm số ProductId duy nhất với $addToSet + $size.
1. Dữ liệu sản phẩm
> db.demo466.insertOne({ ProductPrice: 150, ProductQuantity: 1, ProductName: "Product-1", ActualAmount: 110, ProductProfit: 40, ProductId: 1 });
> db.demo466.insertOne({ ProductPrice: 150, ProductQuantity: 1, ProductName: "Product-1", ActualAmount: 110, ProductProfit: 40, ProductId: 2 });
> db.demo466.insertOne({ ProductPrice: 170, ProductQuantity: 2, ProductName: "Product-2", ActualAmount: 130, ProductProfit: 50, ProductId: 3 });
2. Pipeline aggregation
> db.demo466.aggregate([
{
$group: {
_id: { ProductName: "$ProductName" },
ActualAmount: { $sum: "$ActualAmount" },
ProductQuantity: { $sum: "$ProductQuantity" },
ProductId: { $addToSet: "$ProductId" } // Set duy nhất
}
},
{
$project: {
ProductQuantity: true,
ActualAmount: true,
NumberOfProductInStock: { $size: "$ProductId" } // Đếm unique ProductId
}
}
]);
3. Kết quả
{ "_id": { "ProductName": "Product-2" }, "ActualAmount": 130, "ProductQuantity": 2, "NumberOfProductInStock": 1 }
{ "_id": { "ProductName": "Product-1" }, "ActualAmount": 220, "ProductQuantity": 2, "NumberOfProductInStock": 2 }
Giải thích
- Stage 1 ($group): Gom theo ProductName, sum Amount/Quantity, collect unique ProductId vào mảng
- Stage 2 ($project): Tính
NumberOfProductInStock= size của mảng ProductId (số ID duy nhất)
Mở rộng: Nested $group (2 cấp group)
// Ví dụ: Gom theo Category, sau đó gom theo ProductName trong Category
db.products.aggregate([
{ $group: {
_id: { Category: "$Category", ProductName: "$ProductName" },
totalQty: { $sum: "$Quantity" },
count: { $sum: 1 }
}},
{ $group: {
_id: "$_id.Category",
products: { $push: { ProductName: "$_id.ProductName", totalQty: "$totalQty", variants: "$count" } },
totalProducts: { $sum: 1 }
}}
]);
Mẹo: $addToSet vs $push
$addToSet: Chỉ thêm nếu chưa có → mảng unique (dùng để đếm distinct)$push: Thêm tất cả → mảng có thể trùng (dùng để lấy tất cả giá trị)- Kết hợp
$addToSet+$size= đếm distinct values