Sử dụng $group trong MongoDB aggregation để gom nhóm và tính toán.
Tạo collection dữ liệu phức tạp
> db.demo639.insertOne({
"_id": 1, "CountryName": "US",
"Info1": { "Name": "Chris", "SubjectName": "MySQL", "Marks": 78 },
"Info2": { "Name": "Chris", "SubjectName": "MySQL", "Marks": 78 }
});
> db.demo639.insertOne({
"_id": 2, "CountryName": "UK",
"Info1": { "Name": "Chris", "SubjectName": "MySQL", "Marks": 79 },
"Info2": { "Name": "Chris", "SubjectName": "MySQL", "Marks": 88 }
});
Hiển thị dữ liệu
> db.demo639.find();
Kết quả (2 document):
_id:1 US Info1(Chris,MySQL,78) Info2(Chris,MySQL,78) _id:2 UK Info1(Chris,MySQL,79) Info2(Chris,MySQL,88)
Aggregate $group phức tạp
> db.demo639.aggregate({
$group: {
_id: { Name1: "$Info1.Name", Name2: "$Info2.Name" },
Marks: { $first: "$Info2.Marks" },
Marks: { $sum: "$Info2.Marks" }
}
}).pretty();
Kết quả:
{
"_id" : { "Name1" : "Chris", "Name2" : "Chris" },
"Marks" : 166
}
Giải thích:
_idlà object gom theo cặp (Info1.Name, Info2.Name) - cả hai đều là "Chris"- Lưu ý: Có 2 trường
Markstrong $group - trường sau ($sum) sẽ ghi đè trường trước ($first). Kết quả chỉ có$sum= 78 + 88 = 166 - Đây là ví dụ minh họa cú pháp, thực tế nên đặt tên trường khác nhau:
FirstMarks,TotalMarks
Pattern $group phổ biến:
{
$group: {
_id: "", // Khóa nhóm
count: { $sum: 1 }, // Đếm document
total: { $sum: "$field" }, // Tổng trường số
avg: { $avg: "$field" }, // Trung bình
min: { $min: "$field" }, // Min
max: { $max: "$field" }, // Max
first: { $first: "$field" }, // Giá trị đầu (cần $sort trước)
last: { $last: "$field" }, // Giá trị cuối
values: { $push: "$field" }, // Mảng tất cả giá trị (có trùng)
unique: { $addToSet: "$field" } // Mảng giá trị duy nhất
}
}