You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在MongoDB中统计最近X天的记录数?并使用Chart.js展示最近7天每日维修数据(无数据日默认显示0)

解决MongoDB维修数据统计+Chart.js可视化方案

我来帮你搞定这两个需求,先从最近7天每日工单统计(适配Chart.js)说起,再讲最近X天总记录数统计

一、获取最近7天每日维修工单数量(无记录显示0)

要得到Chart.js需要的[30,40,0,80,75,0,90]这种格式,需要两步:用MongoDB聚合查询统计有数据的日期,再补全缺失日期的0值(数据库层面处理更高效,也可以在前端补全)。

1. MongoDB聚合查询代码

假设你的维修工单集合是Repairs,日期字段是repairDate(必须是Date类型,不是字符串!如果是字符串,需要先通过$toDate转换)。下面的聚合管道会直接返回包含7天数据的数组:

// 计算7天前的起始日期(包含今天,共7天)
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 6);
sevenDaysAgo.setHours(0, 0, 0, 0); // 重置到当天零点,避免时间部分干扰

const pipeline = [
  // 第一步:筛选最近7天的维修记录
  {
    $match: {
      repairDate: { $gte: sevenDaysAgo }
    }
  },
  // 第二步:按日期分组,统计每日工单数量
  {
    $group: {
      _id: { $dateToString: { format: "%Y-%m-%d", date: "$repairDate" } },
      count: { $sum: 1 }
    }
  },
  // 第三步:生成最近7天的所有日期数组
  {
    $addFields: {
      allDates: Array.from({ length: 7 }, (_, i) => {
        const date = new Date(sevenDaysAgo);
        date.setDate(date.getDate() + i);
        return date.toISOString().split('T')[0]; // 转成YYYY-MM-DD格式
      })
    }
  },
  // 第四步:展开日期数组,准备匹配
  { $unwind: "$allDates" },
  // 第五步:左连接,填充无数据日期的count为0
  {
    $group: {
      _id: "$allDates",
      count: { $first: { $ifNull: ["$count", 0] } }
    }
  },
  // 第六步:按日期排序,保证顺序正确
  { $sort: { _id: 1 } },
  // 第七步:提取count数组,输出Chart.js需要的格式
  { $group: { _id: null, data: { $push: "$count" } } },
  { $project: { _id: 0, data: 1 } }
];

// 执行聚合查询
const result = await db.collection('Repairs').aggregate(pipeline).next();
const chartData = result.data; // 这里就是你要的[30,40,0,...]格式

2. Chart.js可视化代码

拿到chartData后,直接用Chart.js生成图表,下面是柱状图的示例(换成折线图只需要修改type'line'):

<!-- 先引入Chart.js -->
<canvas id="repairDailyChart"></canvas>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
// 生成日期标签(比如"10/23", "10/24"...)
const dateLabels = Array.from({ length:7 }, (_,i) => {
  const date = new Date();
  date.setDate(date.getDate() - 6 + i);
  return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' });
});

// 初始化图表
const ctx = document.getElementById('repairDailyChart').getContext('2d');
new Chart(ctx, {
  type: 'bar',
  data: {
    labels: dateLabels,
    datasets: [{
      label: '每日维修工单数量',
      data: chartData, // 替换成上面获取的chartData
      backgroundColor: 'rgba(75, 192, 192, 0.2)',
      borderColor: 'rgba(75, 192, 192, 1)',
      borderWidth: 1
    }]
  },
  options: {
    scales: {
      y: {
        beginAtZero: true, // Y轴从0开始,避免数据失真
        ticks: {
          stepSize: 10 // 刻度间隔,根据你的数据调整
        }
      }
    }
  }
});
</script>

二、统计最近X天的记录总数

这个需求很简单,用countDocuments结合日期筛选即可:

/**
 * 统计最近X天的维修工单总数
 * @param {number} x - 天数(比如7代表最近7天,包含今天)
 * @returns {Promise<number>} 总记录数
 */
async function getRecentXDaysTotal(x) {
  const xDaysAgo = new Date();
  xDaysAgo.setDate(xDaysAgo.getDate() - x + 1); // 包含今天的计算方式
  xDaysAgo.setHours(0, 0, 0, 0); // 重置到当天零点

  return await db.collection('Repairs').countDocuments({
    repairDate: { $gte: xDaysAgo }
  });
}

// 调用示例:统计最近7天总数
const total7Days = await getRecentXDaysTotal(7);
console.log(`最近7天总维修工单:${total7Days}单`);

注意事项

  • 确保repairDate字段是MongoDB的Date类型,如果是字符串格式,需要在查询时用$toDate转换,比如$match里写成repairDate: { $gte: { $toDate: sevenDaysAgo.toISOString() } }
  • 如果你的业务里“最近7天”是指过去7天(不含今天),只需要把sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 6)改成sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7)即可

内容的提问来源于stack exchange,提问作者Ali Parlatti

火山引擎 最新活动