Labor of love , optional lab, chapter 1

This one is kinda difficult to me, so I’am trying to find a solution , some of the operators I thought would help me by reading the forum were :

  • $map
  • $setIntersection
  • $elemMatch
  • $exists

My idea is :

  1. Return an array with the common values in the 3 arrays using $setIntersection.
  2. Since $setIntersection will aso return null and empty arrays , use $map , $elemMatch and $exists to filter out only the array where value is not null or an empty array.
  3. Return the array.
db.movies.aggregate
(
    [
        $project : 
            {
                $map : { input : {$setIntersection : ["$writers","$cast","$directors"]}  , 
                as : "common_value", 
                in : { "common_value" :{$elemMatch : {$exists : true}}} }
            }
    ]
)

This is my ideia but I have been here all morning and I haven’t found a way to make it work yet. Any advice ?

Hi @Simao_Bonvalot,
please check:

1 Like

I’am sorry but that’s not my issue yet. I need help with the pipeline , handling the filtered results.

I would like to know how can I get I make an intersection between the the results of $match.

After matching the arrays that only contain 1 or more elements with $match. , when I use $project I still get empty arrays . What am I doing wrong in the pipelines ?

db.movies.aggregate(
[
 {$match : {$and : [ {writers: {$elemMatch: {$exists: true}}} , {directors: {$elemMatch: {$exists: true}}} , {cast: {$elemMatch : {$exists: true}}} ]}}, 
 {$project: {"labers of love" :{$setIntersection: [writers, cast, directors]}, _id: 0 } } ] ).pretty()

Hi Again,

Totally agree. My bad.
You have a syntactic error. Next time, share the shell output.

{$setIntersection: [writers, cast, directors]}

writers, cast, and directors are interpreted as variables.
you have to target the values of those fields i.e "$writers", "$cast", and "$directors".
You don’t have to use $and
good luck

I don’t understand why this is returning empty arrays., because on the first pipe $match , I filter only the results that are not empty.

This is why I’am assuming the pipeline is not working correctly. The values of $match are not flowing into $project…

In the course they say this

There are times when we want to make sure that the field is an array, and that it is not empty. We can do this within $match : { $match: { writers: { $elemMatch: { $exists: true } }

$setIntersection may return an empty array, eg:

$setIntersection:[ [1,2] , [3,4] ] is []
1 Like

@Imad_Bouteraa , yes , but isn’t $setIntersection dealing with the results from $match , since its a pipeline ?

If so , shouldn’t this NOT return an empty array ?

$match : { $match: { writers: { $elemMatch: { $exists: true } }

@Imad_Bouteraa’s example was, in my opinion, clear that the intersection of 2 or more non-empty array might be empty. For a more specific example:

let directors = [ "imad" ] ;
let writers = [ "steevej" ] ;
let cast = [ "simao" ] ;

then { directors : { $elemMatch : { $exists : true } } is true
then { writers : { $elemMatch : { $exists : true } } is true
then { cast : { $elemMatch : { $exists : true } } is true

but it is clear that no one is director and writer and cast
2 Likes

@steevej Sorry , my bad , I understand now . It will be empty if there are no intersections.

Thanks !

1 Like