用户登录时返回其跑步数据聚合值的问题排查
问题原因与解决方案
核心问题是类型不匹配:
Run.find({ user: req.user.id })能成功,是因为Mongoose的find()方法会自动将字符串类型的req.user.id转换为MongoDB的ObjectId类型,匹配数据库中user字段存储的ObjectId。- 而
aggregate()中的$match操作符不会自动做类型转换,当你传入字符串类型的req.user.id时,无法匹配数据库中ObjectId类型的user字段,导致返回空数组。
解决步骤
1. 转换类型后匹配
导入Mongoose的Types工具,将req.user.id转换为ObjectId再传入$match:
const mongoose = require('mongoose'); const { Types } = mongoose; // 替换原聚合代码中的$match部分 const cumulativeTotals = await Run.aggregate([ { $match: { user: Types.ObjectId(req.user.id) } }, { $group: { _id: null, totalRunTime: { $sum: '$runTime' }, avgRunTime: { $avg: '$runTime' }, totalRunDistance: { $sum: '$runDistance' }, avgRunDistance: { $avg: '$runDistance' }, avgPace: { $avg: '$avgPace' }, totalHeartRate: { $avg: '$avgHeartRate' }, totalActiveCalories: { $sum: '$activeCalories' }, averageActiveCalories: { $avg: '$activeCalories' }, absoluteTotalCalories: { $sum: '$totalCalories' }, avgTotalCalories: { $avg: '$totalCalories' }, } } ])
2. 直接使用ObjectId类型的用户ID
如果你的认证中间件(比如Passport)已经将req.user._id作为ObjectId返回,也可以直接使用:
{ $match: { user: req.user._id } }
验证方法
可以通过以下代码确认类型差异:
console.log(typeof req.user.id); // 输出: string console.log(req.user._id instanceof mongoose.Types.ObjectId); // 输出: true(如果存在的话)
内容的提问来源于stack exchange,提问作者Lofton Gentry
相关产品推荐
相关产品推荐

