Mongoose如何从数据库获取最近7天用户注册数据统计?
Mongoose 实现最近7天用户注册统计方案
前置前提
确保你的UserSchema中createdAt字段为Date类型,推荐直接开启Schema的timestamps配置自动维护创建/更新时间:
const userSchema = new mongoose.Schema({ name: String, email: String }, { timestamps: true }); // 自动生成createdAt、updatedAt字段 // 给createdAt加索引提升查询速度 userSchema.index({ createdAt: -1 }); const User = mongoose.model('User', userSchema);
核心实现代码
1. 计算统计时间边界
// 获取7天前的0点作为统计起始时间 const startDate = new Date(); startDate.setDate(startDate.getDate() - 7); startDate.setHours(0, 0, 0, 0);
2. 执行聚合查询
const statList = await User.aggregate([ // 第一步:过滤出最近7天注册的用户,缩小查询范围 { $match: { createdAt: { $gte: startDate } } }, // 第二步:按自然天分组统计注册数 { $group: { // 按"年-月-日"格式分组,也可以用$dateTrunc(MongoDB 5.0+支持)更简便 _id: { $dateToString: { format: "%Y-%m-%d", date: "$createdAt", timezone: "Asia/Shanghai" } }, count: { $sum: 1 } } }, // 第三步:按日期升序排序,保证时间从早到晚 { $sort: { _id: 1 } } ]);
3. 格式化为要求的输出结构
这里会自动补全没有注册用户的日期,避免统计数据缺项:
// 生成最近7天的所有日期字符串,用于补0 const fullDateList = Array.from({ length: 7 }).map((_, index) => { const d = new Date(startDate); d.setDate(d.getDate() + index); return d.toISOString().split('T')[0]; }); // 组装为要求的filterData格式 const filterData = {}; fullDateList.forEach((dateStr, index) => { const dayKey = `${index + 1}st day`; // 可根据需求调整后缀,比如第3天用rd const statItem = statList.find(item => item._id === dateStr); filterData[dayKey] = statItem ? statItem.count : 0; }); // 最终返回给接口的结果 const result = { filterData };
注意事项
- 如果你的
createdAt字段存储的是字符串格式,需要在$match之前加$addFields阶段把字段转为Date类型:{ $addFields: { createdAt: { $toDate: "$createdAt" } } } - 时区参数
timezone可以根据你的业务所在地调整,避免跨时区统计日期不准 - MongoDB 5.0及以上版本可以用
$dateTrunc替代$dateToString分组,写法更简洁:_id: { $dateTrunc: { date: "$createdAt", unit: "day", timezone: "Asia/Shanghai" } }
内容的提问来源于stack exchange,提问作者Al Imran Hossain
相关产品推荐
相关产品推荐

