Share
Explore

MONGO DB LAB Workbook: Movies and Actors: Creating Predicate Joins

Learning Outcomes:

Using $lookup to correlate various collections.

Step 1: Create a Database containing this Data:

Actors JSON:
[ { "name": "Tom Cruise", "age": 59, "gender": "Male", "movies": ["Mission: Impossible", "Jack Reacher", "Top Gun"] }, { "name": "Angelina Jolie", "age": 46, "gender": "Female", "movies": ["Salt", "Mr. & Mrs. Smith", "Wanted"] }, { "name": "Jason Statham", "age": 53, "gender": "Male", "movies": ["The Transporter", "Crank", "Spy"] }, { "name": "Charlize Theron", "age": 45, "gender": "Female", "movies": ["Atomic Blonde", "Mad Max: Fury Road", "The Italian Job"] }, { "name": "Idris Elba", "age": 49, "gender": "Male", "movies": ["Luther", "Hobbs & Shaw", "The Dark Tower"] }, { "name": "Scarlett Johansson", "age": 36, "gender": "Female", "movies": ["Black Widow", "Lucy", "Ghost in the Shell"] }, { "name": "Chris Hemsworth", "age": 38, "gender": "Male", "movies": ["Extraction", "Thor", "Men in Black: International"] }, { "name": "Emily Blunt", "age": 38, "gender": "Female", "movies": ["Edge of Tomorrow", "Sicario", "The Girl on the Train"] }, { "name": "Matt Damon", "age": 50, "gender": "Male", "movies": ["The Bourne Identity", "Elysium", "The Martian"] }, { "name": "Gal Gadot", "age": 36, "gender": "Female", "movies": ["Wonder Woman", "Fast & Furious", "Keeping Up with the Joneses"] }]

Movies JSON:
[ { "title": "Mission: Impossible - Fallout", "year": 2018, "genre": ["Action", "Adventure", "Thriller"], "actors": ["Tom Cruise", "Rebecca Ferguson", "Henry Cavill"] }, { "title": "Salt", "year": 2010, "genre": ["Action", "Mystery", "Thriller"], "actors": ["Angelina Jolie", "Liev Schreiber", "Chiwetel Ejiofor"] }, { "title": "The Transporter", "year": 2002, "genre": ["Action", "Crime", "Thriller"], "actors": ["Jason Statham", "Qi Shu", "Matt Schulze"] }, { "title": "Atomic Blonde", "year": 2017, "genre": ["Action", "Mystery", "Thriller"], "actors": ["Charlize Theron", "James McAvoy", "John Goodman"] }, { "title": "Luther", "year": 2010, "genre": ["Crime", "Drama", "Mystery"], "actors": ["Idris Elba", "Dermot Crowley", "Michael Smiley"] }, { "title": "Black Widow", "year": 2021, "genre": ["Action", "Adventure", "Sci-Fi"], "actors": ["Scarlett Johansson", "Florence Pugh", "David Harbour"] }, { "title": "Extraction", "year": 2020, "genre": ["Action", "Thriller"], "actors": ["Chris Hemsworth", "Rudhraksh Jaiswal", "Randeep Hooda"] }, { "title": "Edge of Tomorrow", "year": 2014, "genre": ["Action", "Sci-Fi"], "actors": ["Emily Blunt", "Tom Cruise", "Bill Paxton"] }, { "title": "The Bourne Identity", "year": 2002, "genre": ["Action", "Mystery", "Thriller"], "actors": ["Matt Damon", "Franka Potente", "Chris Cooper"] }, { "title": "Wonder Woman", "year": 2017, "genre": ["Action", "Adventure", "Fantasy"], "actors": ["Gal Gadot", "Chris Pine", "Robin Wright"] }]

Write MONGODB code to list all the movies that Tom Cruise is in:
db.movies.find({ actors: "Tom Cruise" })
Student Exercise:
Extend this to using regex and wildcards, $gt, $lt

Correlate between the collections: Write db shell code to list all movies with a female actress
To list all movies with a female actress, you can use MongoDB's $lookup aggregation pipeline stage to join the movies collection with the actors collection based on the actors field.
db.movies.aggregate([ { $lookup: { from: "actors", localField: "actors", foreignField: "name", as: "actorsInfo" } }, { $unwind: "$actorsInfo" }, { $match: { "actorsInfo.gender": "female" } }])
This code first performs a $lookup stage to join the movies collection with the actors collection.
The from field specifies the collection to join with,
localField specifies the field in the movies collection to match on (actors),
foreignField specifies the field in the actors collection to match on (name),
as specifies the name of the new field to add to the documents in the movies collection (actorsInfo).
The $unwind stage then flattens the actorsInfo field to create one document for each actor in the actorsInfo array.
Finally, the $match stage filters the results to only include documents where the actorsInfo.gender field is "female". This will return all movies that have at least one female actress.

Write Mongoose code to do all steps
(1) import the actors and movies collections from text files
(2) find movies with actor Tom Cruise
(3) do correlate between the collections with mongoose code to list all movies with a female actress

Here's the Mongoose code to do all of these steps:
To fix the error, you need to remove the callback function and use async/await instead. The updated code should look like this:

const mongoose = require('mongoose');const fs = require('fs');
// Connect to MongoDBmongoose.connect('mongodb://localhost/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });
// Define schema for actors collectionconst actorSchema = new mongoose.Schema({ name: String, gender: String, age: Number});const Actor = mongoose.model('Actor', actorSchema);
// Define schema for movies collectionconst movieSchema = new mongoose.Schema({ title: String, year: Number, genre: [String], actors: [String]});const Movie = mongoose.model('Movie', movieSchema);
// Import actors and movies collections from text filesconst actorsData = fs.readFileSync('actors.json', 'utf8');const actors = JSON.parse(actorsData);
const moviesData = fs.readFileSync('movies.json', 'utf8');const movies = JSON.parse(moviesData);
(async () => { try { await Actor.insertMany(actors); console.log('Actors imported successfully'); } catch (err) { console.error(err); }
try { await Movie.insertMany(movies); console.log('Movies imported successfully'); } catch (err) { console.error(err); }
try { const moviesWithTomCruise = await Movie.find({ actors: 'Tom Cruise' }); console.log('Movies with Tom Cruise:', moviesWithTomCruise); } catch (err) { console.error(err); }
try { const moviesWithFemaleActresses = await Movie.aggregate([ { $lookup: { from: 'actors', localField: 'actors', foreignField: 'name', as: 'actorsInfo' } }, { $unwind: '$actorsInfo' }, { $match: { 'actorsInfo.gender': 'female' } } ]);
console.log('Movies with female actresses:', moviesWithFemaleActresses); } catch (err) {
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.