MongoDB / $match, $group, $sort, $project

$match, $group, $sort, $project

Aggregation Pipeline-ийн хамгийн их ашиглагддаг stage-үүдийг дэлгэрэнгүй авч үзнэ. Ялангуяа $group дотор ашиглагдах нэгтгэх операторууд нь статистик тооцоололд зайлшгүй хэрэгтэй.

$group дотрох нэгтгэх операторууд

$sum — нийлбэр

javascript
// Борлуулалтын нийт орлого
db.orders.aggregate([
  {
    $group: {
      _id: "$category",
      totalRevenue: { $sum: "$amount" },
    },
  },
]);

// Тоолоход $sum: 1 ашиглана
db.orders.aggregate([{ $group: { _id: "$status", count: { $sum: 1 } } }]);

$avg — дундаж

javascript
// Бүтээгдэхүүн бүрийн дундаж үнэлгээ
db.reviews.aggregate([
  {
    $group: {
      _id: "$productId",
      avgRating: { $avg: "$rating" },
      reviewCount: { $sum: 1 },
    },
  },
]);

$min, $max — хамгийн бага, хамгийн их

javascript
// Хот бүрийн хамгийн залуу ба хамгийн настай хэрэглэгч
db.users.aggregate([
  {
    $group: {
      _id: "$city",
      youngestAge: { $min: "$age" },
      oldestAge: { $max: "$age" },
    },
  },
]);

$count — stage-д тоолох

$count нь $group дотор биш, дангаараа stage болж ашиглагдана:

javascript
db.orders.aggregate([
  { $match: { status: "completed" } },
  { $count: "completedOrders" },
]);
// Үр дүн: { completedOrders: 142 }

$push — бүлгийн утгуудыг массив болгох

javascript
// Хот бүрийн хэрэглэгчдийн нэрсийг жагсаах
db.users.aggregate([
  {
    $group: {
      _id: "$city",
      members: { $push: "$username" },
    },
  },
]);
// { _id: "Улаанбаатар", members: ["bold", "dorj", "od"] }

$addToSet — давхардалгүй массив

javascript
// Захиалга бүрт ашигласан төлбөрийн аргуудыг давхардалгүй жагсаах
db.orders.aggregate([
  {
    $group: {
      _id: "$userId",
      paymentMethods: { $addToSet: "$paymentMethod" },
    },
  },
]);

$project — талбар хувиргах

$project нь талбар сонгохоос гадна шинэ тооцоолсон талбар үүсгэж болдог.

Талбар нэрлэх

javascript
db.users.aggregate([
  {
    $project: {
      _id: 0,
      name: "$username", // username-ийг name болгон нэрлэх
      contact: "$email",
    },
  },
]);

Тооцоолсон талбар

javascript
db.products.aggregate([
  {
    $project: {
      name: 1,
      price: 1,
      // Хөнгөлөлттэй үнэ тооцох
      discountedPrice: { $multiply: ["$price", 0.9] },
      // Нөөц дуусах гэж байгаа эсэх
      lowStock: { $lte: ["$stock", 5] },
    },
  },
]);

Ашиглаж болох аrithmetic операторууд: $add, $subtract, $multiply, $divide.

Pipeline оновчлол

$match-ийг эхэнд тав

javascript
// ❌ Муу — бүх document бүлэглээд дараа нь шүүнэ
db.orders.aggregate([
  { $group: { _id: "$city", total: { $sum: "$amount" } } },
  { $match: { total: { $gt: 1000000 } } },
]);

// ✅ Сайн — эхлээд шүүгээд, цөөн document-тай бүлэглэнэ
db.orders.aggregate([
  { $match: { status: "completed" } },
  { $group: { _id: "$city", total: { $sum: "$amount" } } },
  { $sort: { total: -1 } },
]);

$limit-ийг эрт тав

Зөвхөн хязгаарлагдсан тооны үр дүн хэрэгтэй бол $sort-ийн дараа шууд $limit тав:

javascript
db.products.aggregate([
  { $match: { category: "electronics" } },
  { $sort: { sales: -1 } },
  { $limit: 10 }, // ← эрт тавьснаар дараагийн stage-үүд 10 document-тай ажиллана
  { $project: { name: 1, sales: 1, _id: 0 } },
]);

Бодит жишээ: Тайлан

javascript
// Сар бүрийн орлого, захиалгын тоо, дундаж захиалгын дүн
db.orders.aggregate([
  { $match: { status: "completed" } },
  {
    $group: {
      _id: { $month: "$createdAt" }, // сараар бүлэглэх
      monthlyRevenue: { $sum: "$amount" },
      orderCount: { $sum: 1 },
      avgOrderValue: { $avg: "$amount" },
    },
  },
  { $sort: { _id: 1 } },
]);

// Үр дүн:
// { _id: 1, monthlyRevenue: 4500000, orderCount: 45, avgOrderValue: 100000 }
// { _id: 2, monthlyRevenue: 3200000, orderCount: 32, avgOrderValue: 100000 }
// ...

Дараагийн хичээлд:

$lookup ашиглан өөр collection-ийн өгөгдлийг JOIN хийх талаар үзнэ.