Home  >  Q&A  >  body text

Returns the total value specific to the user when the user is logged in

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粉470645222P粉470645222211 days ago539

reply all(1)I'll reply

  • P粉722409996

    P粉7224099962024-03-23 10:52:36

    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

    reply
    0
  • Cancelreply