Cant complete Chapter 2: Basic Aggregation - Utility Stages Lab: Using Cursor-like Stages

This is the pipeline I came up with so far:

‘’'var pipeline = [{$match : {“tomatoes.viewer.rating” : {$gte : 3.0}}}, {$addFields : {num_favs: {$setIntersection: [[“Sandra Bullock”,“Tom Hanks”, “Julia Roberts”, “Kevin Spacey”, “George Clooney”], “$cast”]}}}, {$addFields : {num_favs : {$size : “$num_favs”}}}, {$sort : {“num_favs” : -1, “tomatoes.viewer.rating” : -1, “title” : -1}}, {$limit : 25}]

db.movies.aggregate(pipeline)’’’

I am getting the following error when executing the above pipeline:

uncaught exception: Error: command failed: {

“operationTime” : Timestamp(1620020717, 1),

“ok” : 0,

“errmsg” : “The argument to $size must be an array, but was of type: null”,

“code” : 17124,

“codeName” : “Location17124”,

“$clusterTime” : {

“clusterTime” : Timestamp(1620020717, 1),

“signature” : {

“hash” : BinData(0,“uGzb6vDpGxtcESLU1KCIkxm1pcg=”),

“keyId” : NumberLong(“6902062171803353090”)

}

}

} : aggregate failed :

_getErrorWithCode@src/mongo/shell/utils.js:25:13

doassert@src/mongo/shell/assert.js:18:14

_assertCommandWorked@src/mongo/shell/assert.js:639:17

assert.commandWorked@src/mongo/shell/assert.js:729:16

DB.prototype._runAggregate@src/mongo/shell/db.js:266:5

DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1058:12

@(shell):1:1

I also tried testing the pipeline by removing the last three stages and setintersection is not working. I am getting empty arrays in all fields.

That’s the way to go. B-)

What database are you using?

Try to replace $addFields with a $match that uses $in to see if you have any documents with the desired actors. Something like (untested):

{ $match :  { cast : { $in : [ ... actors ] } } }

Here is my new pipeline:

var pipeline = [{$match : {$and : [{“tomatoes.viewer.rating” : {$gte : 3.0}}, {cast : {$in : [“Sandra Bullock”, “Tom Hanks”, “Julia Roberts”, “Kevin Spacey”, “George Clooney”]}}]}}, {$addFields : {num_favs: {$setIntersection: [[“Sandra Bullock”,“Tom Hanks”, “Julia Roberts”, “Kevin Spacey”, “George Clooney”], “$cast”]}}}, {$addFields : {num_favs : {$size : “$num_favs”}}}, {$sort : {“num_favs” : -1, “tomatoes.viewer.rating” : -1, “title” : -1}}, {$limit : 25}]

now I am getting a result when aggregating but still not getting the right answer. I assume the 25th document corresponds to the first record in the result for which I get gravity. How do I get the right result?

You are missing one of the requirement, something like the release country.

This is my new pipeline. Still not getting the right result:

var pipeline = [{$match : {$and : [{“tomatoes.viewer.rating” : {$gte : 3.0}},{countries: {$in : [“USA”]}}, {cast : {$in : [“Sandra Bullock”, “Tom Hanks”, “Julia Roberts”, “Kevin Spacey”, “George Clooney”]}}]}}, {$addFields : {num_favs: {$setIntersection: [[“Sandra Bullock”,“Tom Hanks”, “Julia Roberts”, “Kevin Spacey”, “George Clooney”], “$cast”]}}}, {$addFields : {num_favs : {$size : “$num_favs”}}}, {$sort : {“num_favs” : -1, “tomatoes.viewer.rating” : -1, “title” : -1}}, {$limit : 25}]

Please republish your pipeline with proper formatting using triple back ticks or html pre or code tag. We cannot copy your pipeline directly on our system as the quotes are all wrong because it is normal text.

Hi @Daniel_Martinez,

Few things to check in your aggregation pipeline:

  1. In the $match stage, the comma-separated conditions are ANDed by default.

  2. For checking “movies released in USA” you can directly use the condition: "countries": "USA"

  3. You can pre-define an array favorites to reduce the complexity in your pipeline as below:

    var favorites = [ “Sandra Bullock”, “Tom Hanks”, “Julia Roberts”, “Kevin Spacey”, “George Clooney”]

  4. You can use only one $addField stage to find $size of num_favs field.

I would recommend checking the output of each stage before adding any subsequent stage. If you still face any issues, please feel free to reach out.

Kind Regards,
Sonali Mamgain

1 Like

I think the problem is that I shouldn’t have the expression {cast : {$in : favorites}} in match as the expectation is that I also get num_favs: 0 for some documents. The problem is that when I remove the expression and aggregate I get the following error

Error: command failed: {
   "operationTime" : Timestamp(1620885318, 1),
   "ok" : 0,
   "errmsg" : "The argument to $size must be an array, but was of type: null",
   "code" : 17124,
   "codeName" : "Location17124",
   "$clusterTime" : {
      "clusterTime" : Timestamp(1620885318, 1),
      "signature" : {
         "hash" : BinData(0,"90Ejp9zItF7OPD8BHdCBnv97kRw="),
            "keyId" : NumberLong("6931036270290272257")
         }
      }
   } : aggregate failed :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:18:14
_assertCommandWorked@src/mongo/shell/assert.js:639:17
assert.commandWorked@src/mongo/shell/assert.js:729:16
DB.prototype._runAggregate@src/mongo/shell/db.js:266:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1058:12
@(shell):1:1error

That means set intersection is returning null for some fields when it shouldn’t. Help

Hi @Daniel_Martinez,

Using the condition cast: { $in: favorites } in the $match stage will ensure that you do not get null as a result of $setIntersection.

I would highly recommend tidying up your aggregation pipeline first and then debugging the same. I am able to get the right answer using the aggregation pipeline that you have shared.
Alternatively, you could use the condition to prevent null values in the $size operator. Refer to this example: https://docs.mongodb.com/manual/reference/operator/aggregation/size/#example

If you still face any issues, can you please share the edited pipeline?

Kind Regards,
Sonali Mamgain

1 Like