如標題所示,我試圖在用戶登入時從用戶那裡獲取特定數據並聚合所有數據,然後返回聚合數據。我嘗試使用 $match
函數,但沒有運氣。令人沮喪的是我能夠成功返回物件數組中的所有資料。更具體地說,下面的程式碼成功運行並傳回一個物件數組:
const runs = await Run.find({ user: req.user.id })
但是此程式碼沒有,它會傳回一個空數組:
const cumulativeTotals = await Run.aggregate([ { $match: { user: 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' }, } } ])
我不確定為什麼會發生這種情況。它應該傳回的是一個帶有物件的數組,該物件填充了其中的所有聚合資料。
我還知道,如果刪除 $match
它將成功聚合運行集合中的所有數據,所以我認為這與此有關。
以下是所有相關程式碼:
const getRuns = asyncHandler(async (req, res) => { const runs = await Run.find({ user: req.user.id }) const cumulativeTotals = await Run.aggregate([ { $match: { user: 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' }, } } ]) if (!runs) { res.status(400).json({ message: 'No Runs Found for This User' }) return } const response = { runs, cumulativeTotals } res.status(200).json(response) })
P粉7224099962024-03-23 10:52:36
因此,在rickhg12hs 的幫助下,我們能夠確定{match: { user : req.user.id } }
是我試圖將字串與ObjectId 進行比較,這是行不通的。這是因為我設定的 API 將使用者 ID 作為字串傳回,而不是作為 ObjectID。為了確保您比較的是正確的值類型(在本例中為 ObjectID),您可以這樣做:
{ $match: { user: new mongoose.Types.ObjectId(req.user.id) } }
它會取得傳回的字串並將其轉換為新的 ObjectID,並且因為它現在正在比較 ObjectID,所以它可以工作。
顯然,它一直在文檔中,我只是沒有'看起來還不夠仔細