Đếm tần suất giá trị trùng lặp trên nhiều document
Sử dụng aggregation pipeline với $group (2 lần) để đếm số lần xuất hiện của mỗi tên, sau đó xếp hạng và gom nhóm.
1. Dữ liệu: StudentName lặp lại
> db.demo452.insertOne({ StudentName: "John", StudentAge: 21 });
> db.demo452.insertOne({ StudentName: "John", StudentAge: 22 });
> db.demo452.insertOne({ StudentName: "John", StudentAge: 23 });
> db.demo452.insertOne({ StudentName: "David", StudentAge: 24 });
> db.demo452.insertOne({ StudentName: "David", StudentAge: 25 });
2. Pipeline đầy đủ
> db.demo452.aggregate([
// Stage 1: Đếm theo tên
{ $group: { _id: "$StudentName", count: { $sum: 1 } } },
// Stage 2: Sắp xếp giảm dần
{ $sort: { count: -1 } },
// Stage 3: Gom tất cả vào 1 doc
{ $group: { _id: 1, StudentName: { $push: { StudentName: "$_id", count: "$count" } } } },
// Stage 4: Tách top 2 và gom phần còn lại
{ $project: {
first: { $arrayElemAt: ["$StudentName", 0] },
second: { $arrayElemAt: ["$StudentName", 1] },
others: { $slice: ["$StudentName", 2, { $size: "$StudentName" }] }
}},
// Stage 5: Tạo mảng status: top1, top2, others (gộp thành "New Student Name")
{ $project: {
status: [
"$first",
"$second",
{ StudentName: "New Student Name", count: { $sum: "$others.count" } }
]
}},
// Stage 6: Unwind mảng status
{ $unwind: "$status" },
// Stage 7: Format output
{ $project: { _id: 0, StudentName: "$status.StudentName", count: "$status.count" } }
]);
3. Kết quả
{ "StudentName": "John", "count": 3 }
{ "StudentName": "David", "count": 2 }
{ "StudentName": "New Student Name", "count": 0 }
Phiên bản đơn giản hơn (chỉ cần đếm)
db.demo452.aggregate([
{ $group: { _id: "$StudentName", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]);
// Kết quả: { "_id": "John", "count": 3 }, { "_id": "David", "count": 2 }
Ứng dụng thực tế
- Top sản phẩm bán chạy
- Thống kê lỗi theo loại
- Phân tích từ khóa tìm kiếm
- Leaderboard người dùng hoạt động
Mẹo: Dùng $facet (MongoDB 3.4+) để lấy top K + total cùng lúc
db.demo452.aggregate([
{ $group: { _id: "$StudentName", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $facet: {
top5: [{ $limit: 5 }],
totalCount: [{ $count: "total" }]
}}
]);