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

MongoDB Aggregate: หาค่าเฉลี่ยรายวันของจำนวนเอกสารที่บันทึก


คำนวณ Mean Daily Average Count ด้วย $group และ $project

ใช้ $match กรองวันที่, $group หาวันแรกสุดและผลรวม, $project คำนวณค่าเฉลี่ยต่อวันจากช่วงเวลาทั้งหมด

ตัวอย่างข้อมูล

> db.demo451.insertOne({ DueDate: new ISODate("2020-03-15T10:50:35.000Z"), Value: 10 });
> db.demo451.insertOne({ DueDate: new ISODate("2020-03-14T10:50:35.000Z"), Value: 10 });
> db.demo451.insertOne({ DueDate: new ISODate("2020-03-13T10:50:35.000Z"), Value: 10 });

Query คำนวณค่าเฉลี่ยรายวัน

> db.demo451.aggregate([
  { $match: { DueDate: { $lt: new ISODate() } } },
  { $group: {
      _id: null,
      olderDate: { $min: "$DueDate" },
      sumValue: { $sum: "$Value" }
  }},
  { $project: {
      _id: 0,
      averageValue: {
        $divide: [
          "$sumValue",
          { $divide: [{ $subtract: [new ISODate(), "$olderDate"] }, 1000 * 60 * 60 * 24] }
        ]
      }
  }}
]);

ผลลัพธ์

{ "averageValue": 2.475558456547562 }

คำอธิบายสูตร

Average per day = Total Value ÷ Number of days

  • sumValue - ผลรวม Value ทั้งหมด (30)
  • olderDate - วันที่เก่าสุดในข้อมูล
  • new ISODate() - olderDate - มิลลิวินาทีของช่วงเวลา
  • ÷ (1000*60*60*24) - แปลงเป็นวัน
  • sumValue ÷ days - ค่าเฉลี่ยต่อวัน

กรณีใช้จริง (Production)

// ใช้ $dateToString จัดกลุ่มตามวัน แล้ว $avg
db.demo451.aggregate([
  { $match: { DueDate: { $lt: new ISODate() } } },
  { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$DueDate" } }, dailySum: { $sum: "$Value" } } },
  { $group: { _id: null, averageDaily: { $avg: "$dailySum" } } }
]);

วิธีนี้แม่นยำกว่าเพราะคำนวณจากจำนวนวันจริงที่มีข้อมูล ไม่ใช่วันนับจากวันแรกสุด