DbSchema Database Designer

MongoDB $lookup Explained - How to Join Collections



  1. Introduction to MongoDB
  2. Installation & Database Creation
  3. CRUD Operations
  4. Embedded Documents and Arrays
  5. Validation Rules - Enforcing Structure in MongoDB
  6. Visualize MongoDB Relationships (Embedded vs Referenced)
  7. What Is an Index in MongoDB?
  8. Aggregation Pipeline Explained.
  9. $lookup Explained - How to Join Collections (You are here).

What Is $lookup?

The $lookup stage in MongoDB lets you join data from another collection. If you’ve worked with SQL, think of it as the MongoDB version of a LEFT OUTER JOIN.

Use it when you need to bring related data together, like combining movies with their reviews or users with their orders.

You use the .aggregate() method in MongoDB and add $lookup as one of the stages.


Basic Structure

Here’s the basic $lookup syntax:

db.collection.aggregate([
  {
    $lookup: {
      from: "<otherCollection>",
      localField: "<field_in_current>",
      foreignField: "<field_in_other>",
      as: "<output_array_field>"
    }
  }
]);
  • from - the collection you want to join

  • localField - the field in the current collection

  • foreignField - the field in the other collection

  • as - the name of the new array field that stores the results

Example 1: Join Movies with Reviews

We have two collections:

  • movie

  • reviews

Each review stores the movie_id it belongs to.

db.movie.aggregate([
  {
    $lookup: {
      from: "reviews",
      localField: "_id",
      foreignField: "movie_id",
      as: "movie_reviews"
    }
  }
]);

This query adds a movie_reviews array to each movie document containing all matching reviews.

Example 2: Flatten the Result with $unwind

By default, $lookup puts the results in an array. If you want one document per review, use ``$unwind`:


db.movie.aggregate([
  {
    $lookup: {
      from: "reviews",
      localField: "_id",
      foreignField: "movie_id",
      as: "movie_reviews"
    }
  },
  { $unwind: "$movie_reviews" }
]);
  • Why Use $unwind After $lookup?

By default, $lookup adds the matching documents as an array field. For example, movie_reviews will contain a list of all reviews for each movie.

Sometimes this is exactly what you want.

Now each review appears as its own document linked to the movie.

Example 3: Join Across Multiple Levels

You can also chain ``$lookup` stages to bring in more collections. For example, join movie → reviews → users (to see who wrote each review):

db.movie.aggregate([
  {
    $lookup: {
      from: "reviews",
      localField: "_id",
      foreignField: "movie_id",
      as: "movie_reviews"
    }
  },
  { $unwind: "$movie_reviews" },
  {
    $lookup: {
      from: "users",
      localField: "movie_reviews.user_id",
      foreignField: "_id",
      as: "review_user"
    }
  },
  { $unwind: "$review_user" }
]);

This produces one document per movie-review-user combination.

Example 4: Using a Pipeline in $lookup

Since MongoDB 3.6, ``$lookup` can include a pipeline. This gives you more control, such as filtering the joined documents.

db.movie.aggregate([
  {
    $lookup: {
      from: "reviews",
      let: { movieId: "$_id" },
      pipeline: [
        { $match: { $expr: { $eq: ["$movie_id", "$$movieId"] } } },
        { $project: { user_id: 1, rating: 1, _id: 0 } }
      ],
      as: "filtered_reviews"
    }
  }
]);

Here, only selected fields (user_id, rating) are kept in filtered_reviews.

Summary

The $lookup stage lets you combine collections in MongoDB - just like a join in SQL.

You’ve learned how to:

  • Use $lookup for simple joins
  • Flatten results with $unwind
  • Chain multiple $lookup stages
  • Use pipelines inside $lookup for advanced filtering

This is especially useful when visualized in DbSchema, where you can see relationships as diagrams.

Visual Design & Schema Diagram

➤ Create and manage your database schema visually through a user-friendly graphical interface.

➤ Easily arrange tables, columns, and foreign keys to simplify complex database structures, ensuring clarity and accessibility.

GIT & Collaboration
Version Control & Collaboration

➤ Manage schema changes through version control with built-in Git integration, ensuring every update is tracked and backed up.

➤ Collaborate efficiently with your team to maintain data integrity and streamline your workflow for accurate, consistent results.

Data Explorer & Query Builder
Relational Data & Query Builder

➤ Seamlessly navigate and visually explore your database, inspecting tables and their relationships.

➤ Build complex SQL queries using an intuitive drag-and-drop interface, providing instant results for quick, actionable insights.

Interactive Documentation & Reporting
HTML5 Documentation & Reporting

➤ Generate HTML5 documentation that provides an interactive view of your database schema.

➤ Include comments for columns, use tags for better organization, and create visually reports.