0
votes

I'm following the aggregation pipeline course on MongoDB university.

Here is how the "movies" collection is formatted.

{
    "_id" : ObjectId("573a1390f29313caabcd4cf1"),
    "title" : "Ingeborg Holm",
    "cast" : [
        "Aron Lindgren",
        "Erik Lindholm",
    ],
    "imdb" : {
        "rating" : 7,
    },
}

Here is my aggregation:

db.movies.aggregate( [
  { $unwind: { path: "$cast" } },
  { $set: { "average": 0 } },
  { $group: { 
    _id: "$cast",
    numFilms: { $sum: 1 },
    average: { $avg: { $add: ["$average", "$imdb.rating"] } }, //failed here
  }}
] )

What I'm trying to do:

Calculate the average of rating (imdb.rating) based for every movies of each cast.

What currently happen:

An error occured at

$add: ["$average", "$rating"]

with the follwoing message error:

"errmsg" : "$add only supports numeric or date types, not string",

Question:

Does anyone can explain why $rating is consider as a string ?

I provide above a example of how the "movies" collection is formatted. It seem that $add failed with "$imdb.rating" only when called within $group (and work normally outside of $group when using "$imdb.rating")

Is there another way to calculate the average ?

1
Do you have any records with imdb.rating: "" ? - Tushar Gupta - curioustushar
Indeed, there was a case when imdb.rating was equal to "" - S7_0
Perfect, you can remove the "" values or set them to 0. Or you can use $convert as mentioned in the answer. - Tushar Gupta - curioustushar

1 Answers

0
votes

Use $toInt

 $add: [ { "$toInt": "$imdb.rating" } ]

Better use to $convert handle the error and null cases.

Demo - https://mongoplayground.net/p/gOo52xlDBLM

$avg: {
  $add: [
    $average,
    {
      $convert: {
        input: "$imdb.rating",
        to: "int",
        onError: 0,
        onNull: 0
      }
    }
  ]
},