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

Tăng tốc phase $group trong MongoDB Aggregation

Phase $group trong Aggregation thường tốn tài nguyên nhất (bộ nhớ, CPU) vì phải gom nhóm toàn bộ dữ liệu. Để **tăng tốc $group**, nguyên tắc cốt lõi là **giảm thiểu dữ liệu đầu vào** trước khi group: lọc sớm ($match), chiếu trường cần thiết ($project), và tận dụng index.

1. Tạo dữ liệu: 1 tài liệu chứa mảng 10 số

> db.demo423.insertOne({ "Information": [101, 110, 87, 110, 98, 115, 101, 115, 89, 115] });

2. Pipeline tối ưu: Tìm 2 giá trị xuất hiện nhiều nhất (Top 2 Frequency)

> db.demo423.aggregate([
    { $project: { _id: 0, Information: 1 } },      // 1. Chỉ lấy trường cần thiết (giảm payload)
    { $unwind: "$Information" },                    // 2. Bật mảng thành stream các số
    { $group: { _id: "$Information", frequency: { $sum: 1 } } }, // 3. Group đếm tần suất
    { $sort: { frequency: -1 } },                   // 4. Sắp xếp giảm dần theo tần suất
    { $limit: 2 }                                   // 5. Chỉ lấy top 2 (giảm output)
]);

3. Kết quả

{ "_id": 115, "frequency": 3 }
{ "_id": 110, "frequency": 2 }

Các kỹ thuật tối ưu $group:

  • $match đầu tiên: Lọc document trước khi $unwind/$group (dùng index).
  • $project sớm: Chỉ giữ trường cần group/sort, bỏ _id, trường lớn không dùng.
  • Allow Disk Use: Nếu group lớn > 100MB RAM, thêm { allowDiskUse: true } để spill ra disk (chậm hơn nhưng không crash).
  • Index hỗ trợ: Index trên trường $match/$sort giúp giảm input vào $group.
  • $limit sớm: Nếu chỉ cần top N, $limit sau $sort (như ví dụ).
  • Tránh $group lồng nhau: Dùng $facet hoặc restructure data.

Lưu ý: Ví dụ gốc chỉ có 1 document -> $unwind tạo 10 doc -> group nhẹ. Thực tế collection lớn thì $match/$project đầu tiên cực quan trọng.