Returns the total value specific to the user when the user is logged in
P粉470645222
P粉470645222 2024-03-22 12:45:30
0
1
629

As the title says, I am trying to get specific data from the user when they are logged in and aggregate all the data and then return the aggregated data. I tried using the $match function but no luck. What's frustrating is that I'm able to successfully return all the data in the object array. More specifically, the following code runs successfully and returns an array of objects:

const runs = await Run.find({ user: req.user.id })

But this code doesn't, it returns an empty array:

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' },
      }
    }
  ])

I'm not sure why this is happening. What it should return is an array with an object populated with all the aggregated data in it.

I also know that if I remove $match it will successfully aggregate all the data in the running collection, so I think that has something to do with that.

Here are all the relevant codes:

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粉470645222
P粉470645222

reply all(1)
P粉722409996

So with the help of rickhg12hs we were able to determine that {match: { user : req.user.id } } is me trying to compare a string to an ObjectId, this will not work. This is because the API I set up returns the user ID as a string, not as an ObjectID. To make sure you're comparing the correct value type (ObjectID in this case), you can do this:

{ $match: { user: new mongoose.Types.ObjectId(req.user.id) } }

It takes the returned string and converts it to a new ObjectID, and since it's now comparing ObjectIDs, it works.

Apparently it was in the documentation all along, I just didn't look carefully enough

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template