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

Tính trung bình ngày (Mean daily average) số document ghi nhận MongoDB

Tính trung bình số lượng document ghi nhận mỗi ngày

Sử dụng aggregation với $group tìm ngày cũ nhất, $sum tổng giá trị, $project tính toán số ngày và trung bình.

1. Dữ liệu: DueDate + Value

> 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 });

2. Pipeline tính trung bình ngày

> 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  // ms → days
                ]}
            ]
        }
    }}
]);

3. Kết quả

{ "averageValue": 2.475558456547562 }

Giải thích công thức

averageValue = sumValue / ((now - oldestDate) / ms_per_day)

  • sumValue: Tổng Value = 30
  • olderDate: Ngày sớm nhất = 2020-03-13
  • now - olderDate: Khoảng cách mili-giây từ 13/3 đến hiện tại
  • Chia cho 86,400,000 (ms/ngày) → số ngày
  • 30 / số ngày ≈ 2.48 document/ngày

Cách tốt hơn: Group theo ngày thực tế

db.demo451.aggregate([
    { $match: { DueDate: { $lt: new ISODate() } } },
    { $group: {
        _id: { $dateToString: { format: "%Y-%m-%d", date: "$DueDate" } },
        dailyCount: { $sum: 1 },
        dailySum: { $sum: "$Value" }
    }},
    { $group: {
        _id: null,
        avgDailyCount: { $avg: "$dailyCount" },
        avgDailySum: { $avg: "$dailySum" },
        days: { $sum: 1 }
    }}
]);

Cách này tính trung bình dựa trên các ngày thực sự có dữ liệu, không giả định dữ liệu đều đặn mỗi ngày.

Lưu ý

  • Ví dụ gốc dùng new ISODate() trong pipeline → kết quả thay đổi theo thời gian chạy
  • Trong production, hãy truyền tham số ngày cố định từ application
  • Dùng $dateTrunc (MongoDB 5.0+) để gom nhóm theo ngày/giờ chính xác hơn