简体   繁体   中英

MongoDB Aggregate sum nested number array

I have the following document structure

{
            "_id": "60b7b7c784bd6c2a1ca57f29",
            "user": "607c58578bac8c21acfeeae1",
            "exercises": [
                {
                    "executed_reps": [8,7],
                    "_id": "60b7b7c784bd6c2a1ca57f2a",
                    "exercise_name": "Push up"
                },
                {
                    "executed_reps": [5,5],
                    "_id": "60b7b7c784bd6c2a1ca57f2b",
                    "exercise_name": "Pull up"
                }
            ],
        }

In aggregation, I am trying to sum all the executed_reps so the end value in this example should be 25 (8+7+5+5).

Here is the code I have so far:

const exerciseStats = await UserWorkout.aggregate([
    {
        $match: {
            user: { $eq: ObjectId(req.query.user) },
        },
    },
    { $unwind: '$exercises' },
    {
        $group: {
            _id: null,
            totalReps: {
                $sum: {
                    $reduce: {
                        input: '$exercises.executed_reps',
                        initialValue: '',
                        in: { $add: '$$this' },
                    },
                },
            },
        },
    },
]);

This gives a result of 5 for totalReps . What am I doing wrong?

Well 10 minutes later I found the solution myself:

UserWorkout.aggregate([
    {
        $match: {
            user: { $eq: ObjectId(req.query.user) },
        },
    },
    { $unwind: '$exercises' },
    {
        $project: {
            total: { $sum: '$exercises.executed_reps' },
        },
    },
    {
        $group: {
            _id: null,
            totalExercises: { $sum: '$total' },
        },
    },])

Had to use $project first. :)

You can do it like this:

const exerciseStats = await UserWorkoutaggregate([
  {
    "$addFields": {
      "total": {
        "$sum": {
          "$map": {
            "input": "$exercises",
            "as": "exercise",
            "in": {
              "$sum": "$$exercise.executed_reps"
            }
          }
        }
      }
    }
  }
])

Here is the working example: https://mongoplayground.net/p/5_fsPgSh8EP

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM