Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

MongoDB หาค่า Min/Max จากเอกสารที่มี Duplicate Records ด้วย Aggregation

Aggregation Pipeline ใน MongoDB รองรับ $min และ $max ใน Stage $group สำหรับหาค่าต่ำสุด/สูงสุด แม้ข้อมูลจะมี Duplicate เนื้อหานี้สาธิตการหา Min/Max ของ Field Score

ตัวอย่างข้อมูลทดสอบ (มี Duplicate Score 60)

> db.demo167.insertOne({"Score":60});
{ "acknowledged": true, "insertedId": ObjectId("5e3693a79e4f06af551997d1") }

> db.demo167.insertOne({"Score":80});
{ "acknowledged": true, "insertedId": ObjectId("5e3693ab9e4f06af551997d2") }

> db.demo167.insertOne({"Score":60});
{ "acknowledged": true, "insertedId": ObjectId("5e3693ad9e4f06af551997d3") }

> db.demo167.insertOne({"Score":90});
{ "acknowledged": true, "insertedId": ObjectId("5e3693b09e4f06af551997d4") }

> db.demo167.insertOne({"Score":89});
{ "acknowledged": true, "insertedId": ObjectId("5e3693b69e4f06af551997d5") }

แสดงข้อมูลทั้งหมด

> db.demo167.find();
{
  "_id": ObjectId("5e3693a79e4f06af551997d1"),
  "Score": 60
}
{
  "_id": ObjectId("5e3693ab9e4f06af551997d2"),
  "Score": 80
}
{
  "_id": ObjectId("5e3693ad9e4f06af551997d3"),
  "Score": 60
}
{
  "_id": ObjectId("5e3693b09e4f06af551997d4"),
  "Score": 90
}
{
  "_id": ObjectId("5e3693b69e4f06af551997d5"),
  "Score": 89
}

Aggregation Query Min/Max

> var d = [
  {
    $group: {
      _id: "id",
      MinimumValue: { $min: "$Score" },
      MaximumValue: { $max: "$Score" }
    }
  }
];
> db.demo167.aggregate(d);

ผลลัพธ์

{ "_id": "id", "MinimumValue": 60, "MaximumValue": 90 }

คำอธิบาย

  • $group: { _id: "id" }: Group ทุก Document เป็น Group เดียว (Constant Key)
  • $min: "$Score": หาค่าน้อยสุด (60) - Duplicate ไม่ส่งผล
  • $max: "$Score": หาค่ามากสุด (90)
  • Duplicate Handling: $min/$max มองค่า Unique Values เท่านั้น (Duplicate ไม่เปลี่ยนผลลัพธ์)
  • Operator เพิ่มเติมใน $group:
    • $sum: ผลรวม
    • $avg: ค่าเฉลี่ย
    • $first, $last: ค่าแรก/สุดท้าย (ต้อง Sort ก่อน)
    • $push, $addToSet: สร้าง Array
  • Group By Field: { $group: { _id: "$category", minScore: { $min: "$Score" } } }

Alternative: find().sort().limit()

// Min
db.demo167.find().sort({Score: 1}).limit(1)
// Max
db.demo167.find().sort({Score: -1}).limit(1)

วิธีนี้ใช้ Index ได้ เร็วกว่าสำหรับ Single Value แต่ไม่ได้ทั้ง Min/Max พร้อมกัน