Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Đếm giá trị lặp lại across documents MongoDB với Aggregation

Đế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" }]
    }}
]);