Muirik
Muirik

Reputation: 6289

Second $project Stage Producing Unexpected Result in MongoDB Aggregation

I am trying to run some aggregation in my MongoDB backend where I calculate a value and then add that calculated value to another value. The first step is working, but the second step produces a value of null, and I'm trying to understand why, and how to fix it.

This is what my aggregation look like:

db.staff.aggregate({
    $project: {
      _id: 1,
      "workloadSatisfactionScore": {
          $cond: [ { $eq: [ "$workload.shiftAvg", 0 ] }, "N/A", { $divide: [ "$workload.shiftAvg", "$workload.weeklyShiftRequest.minimum" ] } ]
      }
    },
    $project: {
      _id: 1,
      totalScore: {
        $sum: [ "$workloadSatisfactionScore", 10 ]
      },
    }
})

Even though the first $project stage produces documents with a numeric result or null for 'workloadSatisfactionScore', after the second $project stage, ALL documents have a value of null for 'totalScore'.

What I should get is whatever the value of 'workloadSatisfactionScore' is, added to 10. But as I say, all I get is null for all documents. What looks incorrect here?

As an example, one particular document in my collection returns a value of 0.9166666666666666 for "workloadSatisfactionScore". So when that is plugged into the second $project stage I'd expect a value of 10.9166666666666666 for 'totalScore'. But, as I say, instead I get null for that document, and all other documents.

Upvotes: 1

Views: 24

Answers (1)

chridam
chridam

Reputation: 103305

It's possible that by the time the second $project pipeline is reached, workloadSatisfactionScore could be a string i.e. with the value "N/A" which will result in null when $add or $sum is used with a non-numerical value.

No need for the second project pipeline, you can add the value in the other conditional which handles the non-numerical part without passing it down the pipeline:

db.staff.aggregate({
    "$project": {
        "_id": 1,
        "totalScore": {
            "$cond": [ 
                { "$eq": [ "$workload.shiftAvg", 0 ] }, 
                "N/A",
                { "$add":  [
                    10,
                    { "$divide": [ 
                        "$workload.shiftAvg", 
                        "$workload.weeklyShiftRequest.minimum" 
                    ] }
                ] }
            ]
        }
    }
})

Upvotes: 1

Related Questions