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

MongoDB $avg คืนค่า -Infinity เมื่อมีค่า -Infinity ในข้อมูล

Operator $avg ใน MongoDB Aggregation จะคืนค่า -Infinity หากข้อมูลที่นำมาคำนวณมีค่า -Infinity อยู่ เนื้อหานี้สาธิตพฤติกรรมนี้โดย Group ตาม Field seq

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

> db.demo5.insertOne({ "_id": 100, "seq": 10, "Value": -Infinity });
{ "acknowledged": true, "insertedId": 100 }

> db.demo5.insertOne({ "_id": 101, "seq": 10, "Value": 50 });
{ "acknowledged": true, "insertedId": 101 }

> db.demo5.insertOne({ "_id": 102, "seq": 20, "Value": 60 });
{ "acknowledged": true, "insertedId": 102 }

> db.demo5.insertOne({ "_id": 103, "seq": 20, "Value": 50 });
{ "acknowledged": true, "insertedId": 103 }

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

> db.demo5.find();
{
  "_id": 100, "seq": 10, "Value": -Infinity
}
{
  "_id": 101, "seq": 10, "Value": 50
}
{
  "_id": 102, "seq": 20, "Value": 60
}
{
  "_id": 103, "seq": 20, "Value": 50
}

Aggregation Group By seq และ $avg

> db.demo5.aggregate([
  { $group: { "_id": "$seq", "average": { $avg: "$Value" } } }
]);

ผลลัพธ์

{
  "_id": 20,
  "average": 55
}
{
  "_id": 10,
  "average": -Infinity
}

คำอธิบาย

  • Group seq: 20: ค่า 60 และ 50 → Average = (60+50)/2 = 55
  • Group seq: 10: ค่า -Infinity และ 50 → Average = -Infinity (เพราะ -Infinity + 50 = -Infinity)
  • Mathematical Rule: -Infinity + Any Finite Number = -Infinity
  • NaN Handling: หากมี NaN → $avg คืน NaN
  • Null/Missing: ถูก Ignore (ไม่รวมในการนับ)
  • การป้องกัน: Filter Out -Infinity ก่อน Group:
    db.demo5.aggregate([
      { $match: { Value: { $ne: -Infinity } } },
      { $group: { _id: "$seq", average: { $avg: "$Value" } } }
    ])
  • หรือใช้ $cond ใน $project แปลง -Infinity เป็น Null ก่อน

Operator ที่เกี่ยวข้อง

  • $sum: -Infinity + 50 = -Infinity
  • $min: -Infinity (ค่าน้อยที่สุด)
  • $max: 50 (ค่ามากที่สุด ระหว่าง -Infinity และ 50)
  • $stdDevPop, $stdDevSamp: คืน NaN หากมี -Infinity