Bird
Raised Fist0
MongoDBquery~5 mins

$lookup for joining collections in MongoDB

Choose your learning style10 modes available
Introduction

$lookup helps you combine data from two collections in MongoDB, like joining tables in a spreadsheet. It lets you see related information together in one place.

You want to see orders with customer details in one result.
You need to combine product info with reviews stored separately.
You want to list employees along with their department info.
You want to merge user profiles with their activity logs.
You want to show blog posts with their comments together.
Syntax
MongoDB
db.collection.aggregate([
  {
    $lookup: {
      from: "otherCollection",
      localField: "fieldInThisCollection",
      foreignField: "fieldInOtherCollection",
      as: "newFieldName"
    }
  }
])

from is the collection you want to join with.

localField is the field in your current collection.

foreignField is the matching field in the other collection.

as is the name of the new array field that will hold matched documents.

Examples
Join orders with customers using customerId and _id fields. The matched customer data will be in customerInfo array.
MongoDB
db.orders.aggregate([
  {
    $lookup: {
      from: "customers",
      localField: "customerId",
      foreignField: "_id",
      as: "customerInfo"
    }
  }
])
Join posts with comments by matching _id in posts with postId in comments. Comments appear in commentsList array.
MongoDB
db.posts.aggregate([
  {
    $lookup: {
      from: "comments",
      localField: "_id",
      foreignField: "postId",
      as: "commentsList"
    }
  }
])
Sample Program

This example creates two collections: orders and customers. Then it uses $lookup to join orders with their customer details. The result shows each order with an array customerDetails containing matching customer info.

MongoDB
db.orders.insertMany([
  { _id: 1, item: "Pen", customerId: 101 },
  { _id: 2, item: "Notebook", customerId: 102 }
])

db.customers.insertMany([
  { _id: 101, name: "Alice" },
  { _id: 102, name: "Bob" }
])

// Now join orders with customers

db.orders.aggregate([
  {
    $lookup: {
      from: "customers",
      localField: "customerId",
      foreignField: "_id",
      as: "customerDetails"
    }
  }
]).toArray()
OutputSuccess
Important Notes

The $lookup stage adds an array field even if only one match exists.

If no match is found, the array will be empty.

You can use $unwind after $lookup to flatten the array if you want one document per match.

Summary

$lookup joins two collections by matching fields.

It creates a new array field with matching documents from the other collection.

Useful to combine related data stored separately for easier reading and analysis.

Practice

(1/5)
1. What does the $lookup stage do in a MongoDB aggregation pipeline?
easy
A. It deletes documents from a collection.
B. It joins documents from two collections based on a matching field.
C. It sorts documents in ascending order.
D. It updates documents with new values.

Solution

  1. Step 1: Understand the purpose of $lookup

    $lookup is used to combine documents from two collections by matching fields.
  2. Step 2: Compare with other options

    Deleting, sorting, or updating documents are different operations and not related to $lookup.
  3. Final Answer:

    It joins documents from two collections based on a matching field. -> Option B
  4. Quick Check:

    $lookup joins collections = A [OK]
Hint: Remember: $lookup is like a join in SQL [OK]
Common Mistakes:
  • Confusing $lookup with update or delete operations
  • Thinking $lookup sorts documents
  • Assuming $lookup modifies documents instead of joining
2. Which of the following is the correct syntax for a basic $lookup stage in MongoDB?
easy
A. { $lookup: { from: 'other', localField: 'id', foreignField: 'userId', joinAs: 'joinedData' } }
B. { $lookup: { collection: 'other', localKey: 'id', foreignKey: 'userId', output: 'joinedData' } }
C. { $lookup: { from: 'other', localField: 'id', foreignField: 'userId', as: 'joinedData' } }
D. { $lookup: { from: 'other', localField: 'id', foreignField: 'userId' } }

Solution

  1. Step 1: Identify correct field names in $lookup

    The correct keys are from, localField, foreignField, and as.
  2. Step 2: Check each option

    { $lookup: { from: 'other', localField: 'id', foreignField: 'userId', as: 'joinedData' } } uses all correct keys and syntax. Options A, B, and C have incorrect or missing keys.
  3. Final Answer:

    { $lookup: { from: 'other', localField: 'id', foreignField: 'userId', as: 'joinedData' } } -> Option C
  4. Quick Check:

    Correct $lookup keys = D [OK]
Hint: Use keys: from, localField, foreignField, as [OK]
Common Mistakes:
  • Using wrong key names like collection or joinAs
  • Omitting the 'as' field for output array
  • Missing foreignField or localField keys
3. Given two collections: orders with documents { _id: 1, productId: 101 } and products with documents { _id: 101, name: 'Pen' }, what will be the result of this aggregation on orders?
{ $lookup: { from: 'products', localField: 'productId', foreignField: '_id', as: 'productInfo' } }
medium
A. [{ _id: 1, productId: 101, productInfo: [{ _id: 101, name: 'Pen' }] }]
B. [{ _id: 1, productId: 101, productInfo: [] }]
C. [{ _id: 1, productId: 101 }]
D. SyntaxError

Solution

  1. Step 1: Match localField and foreignField values

    The productId in orders is 101, which matches _id 101 in products.
  2. Step 2: Understand $lookup output

    The matching product document is added as an array in productInfo.
  3. Final Answer:

    [{ _id: 1, productId: 101, productInfo: [{ _id: 101, name: 'Pen' }] }] -> Option A
  4. Quick Check:

    Matching product added in array = B [OK]
Hint: Matched docs appear in array named by 'as' [OK]
Common Mistakes:
  • Expecting productInfo to be a single object, not an array
  • Thinking no match means error instead of empty array
  • Ignoring the 'as' field name in output
4. What is wrong with this $lookup stage?
{ $lookup: { from: 'users', localField: 'userId', foreignField: 'id', as: 'userDetails' } }
Assuming the users collection uses _id as the user ID field.
medium
A. The 'as' field cannot be 'userDetails'.
B. The localField should be 'id' instead of 'userId'.
C. The 'from' field should be 'user' not 'users'.
D. The foreignField should be '_id' instead of 'id'.

Solution

  1. Step 1: Check foreignField correctness

    The users collection uses _id as the ID field, so foreignField must be '_id'.
  2. Step 2: Verify other fields

    localField and as are valid; collection name 'users' is correct.
  3. Final Answer:

    The foreignField should be '_id' instead of 'id'. -> Option D
  4. Quick Check:

    foreignField must match actual field = C [OK]
Hint: Match foreignField to actual field name in other collection [OK]
Common Mistakes:
  • Using wrong foreignField name
  • Changing 'as' field unnecessarily
  • Mistaking collection name pluralization
5. You have two collections: students with { _id: 1, name: 'Alice' } and grades with multiple documents per student like { studentId: 1, score: 85 }. How do you write a $lookup to get each student with all their grades in an array called allGrades?
hard
A. { $lookup: { from: 'grades', localField: '_id', foreignField: 'studentId', as: 'allGrades' } }
B. { $lookup: { from: 'grades', localField: 'studentId', foreignField: '_id', as: 'allGrades' } }
C. { $lookup: { from: 'grades', localField: 'name', foreignField: 'studentId', as: 'allGrades' } }
D. { $lookup: { from: 'grades', localField: '_id', foreignField: 'score', as: 'allGrades' } }

Solution

  1. Step 1: Identify matching fields between collections

    students._id matches grades.studentId, so these are the fields to join on.
  2. Step 2: Write $lookup with correct fields and output array name

    Use from: 'grades', localField: '_id', foreignField: 'studentId', and as: 'allGrades'.
  3. Final Answer:

    { $lookup: { from: 'grades', localField: '_id', foreignField: 'studentId', as: 'allGrades' } } -> Option A
  4. Quick Check:

    Match student _id to grades studentId = A [OK]
Hint: Join on matching ID fields, output array named by 'as' [OK]
Common Mistakes:
  • Swapping localField and foreignField
  • Using wrong fields like name or score for join
  • Incorrect output array name
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard