M121 Chapter 2 lab Cursor Stages

I need a nudge… I can get the fields necessary to get the answer.

Title
Tomato rating
Title
Cast

I can compare the cast field to the favorites.
(I didn’t add a favorite array… I specified the array in the $setIntersection option)

So… I can get a print out of the movie title, the tomato rating, cast, and the array of favorites that match…

But I am having trouble counting the number of entries into the num_favs from the comparison.

I have the addFields creating the num_favs array by comparing the array of favorites to the cast array.

My issue is counting the number of entries in the num_fav array…

I used a project operator to aggregate the “num_favs” field

{   $project :
        {
            "num_favs" : 
                {
                   $cond:
                    {
                       if:{$isArray: "$num_favs"}, then: {$size: "$num_favs"}, else: "0"
                    }
                }
        }
}, 

I save this and I am only getting a one in the field for num_favs. This would lead me to believe that my $setIntersection is not working properly… Am I on the right track?

I got the same problem as you, but i fixed it with the following query

{$project:{common:{$setIntersection: [ “$cast”, favorites ] }}}, {$addFields:{num_favs:{$cond:{if:{$isArray:"$common"}, then: {$size:"$common"}, else: 0 }}}},

When working with arrays, I like to get rid of the non interesting ones with a match stage, that simplifies the rest of the pipeline. For example:

> // starting with the following collection
> db.arrays.find()
{ "_id" : 0, "a" : 1 }
{ "_id" : 1, "a" : [ ] }
{ "_id" : 2, "a" : [ 1 ] }
{ "_id" : 3 }
> // this simple match stage will only keep documents
> // that have a non empy array
> match = { "$match" : { "a.0" : { "$exists" : true } } }
{ "$match" : { "a.0" : { "$exists" : true } } }
> db.arrays.aggregate( match )
{ "_id" : 2, "a" : [ 1 ] }
> // then there is no need for $cond and if/then/else

Thanks… I’ll try this.

I am looking at your response and I am curious on one thing. Per your response

> // starting with the following collection
> db.arrays.find()
{ "_id" : 0, "a" : 1 }
{ "_id" : 1, "a" : [ ] }
{ "_id" : 2, "a" : [ 1 ] }
{ "_id" : 3 }
> // this simple match stage will only keep documents
> // that have a non empy array
> match = { "$match" : { "a.0" : { "$exists" : true } } }
{ "$match" : { "a.0" : { "$exists" : true } } }
> db.arrays.aggregate( match )
{ "_id" : 2, "a" : [ 1 ] }
> // then there is no need for $cond and if/then/else

On the line just after the third comment

> match = { "$match" : { "a.0" : { "$exists" : true } } }
{ "$match" : { "a.0" : { "$exists" : true } } }

Can you explain the to exact $match statements? Also… I was under the understanding that " " isn’t required for operators in the aggregation pipeline… am I correct?

I’m struggling to understand how two exact $match operations ensure that empty arrays are not included.

I got the answer… But I went about it differently than what you all are saying.

I am VERY interested in if you can declare a variable inside the var pipeline declaration. To my knowledge, you cannot… I tried to use the $$farorites when creating the array… Didn’t work… I tried to just define a favorites field in the $addField section… Again… Didn’t work…

So I ended up just using an array inside the $setIntersection operator with the contents of the favorites array in the example…

I would love to know how to get this array into the aggregation pipeline… From my understanding… to load it, I would have to use the $push operator to actually get the array loaded…

Am I thinking correctly???

Any thoughts or recommendations would be well received.

The field a.0 refers to the first element of the array. So if a.0 exists, then a is a non-empty array.

It is not in some programming languages, for example, the mongo shell. But since I am using some languages where it is required, like Java, I always use them.

In JavaScript and in the shell, which is JS based, you simply do:

mongo shell prompt> favorites = [ "steevej" , "david" , "mongo" ]
// the next line is the output from the shell
[ "steevej", "david", "mongo" ]
// then you use it as any JS variable
// Note that there is no quotes, we do not want the string "favorites"
// but the variable favorites
mongo shell prompt> db.movies.find( { "cast" : [ "$in" : favorites ] } )
// there is no output in this case because we (the favorites) do not
// appear in any movie
mongo shell prompt>

I understand this… But if you look at your terminal, there are two $match statements that are exactly the same… What is the reason for this?

The second one is the output from the shell.

Ok. Thanks. I’ve just never seen terminal outputs like that