Bird
Raised Fist0
MongoDBquery~20 mins

Graph lookup for recursive data in MongoDB - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Graph Lookup Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ query_result
intermediate
2:00remaining
Find all subordinates of an employee using $graphLookup
Given a collection employees with documents containing _id, name, and manager_id, which query correctly finds all employees under the manager with _id: 1?
MongoDB
db.employees.aggregate([
  {
    $graphLookup: {
      from: "employees",
      startWith: "$_id",
      connectFromField: "_id",
      connectToField: "manager_id",
      as: "subordinates"
    }
  },
  {
    $match: { _id: 1 }
  }
])
A
db.employees.aggregate([
  {
    $graphLookup: {
      from: "employees",
      startWith: "manager_id",
      connectFromField: "_id",
      connectToField: "manager_id",
      as: "subordinates"
    }
  },
  {
    $match: { _id: 1 }
  }
])
B
db.employees.aggregate([
  {
    $graphLookup: {
      from: "employees",
      startWith: 1,
      connectFromField: "_id",
      connectToField: "manager_id",
      as: "subordinates"
    }
  }
])
C
db.employees.aggregate([
  {
    $match: { _id: 1 }
  },
  {
    $graphLookup: {
      from: "employees",
      startWith: "$manager_id",
      connectFromField: "_id",
      connectToField: "manager_id",
      as: "subordinates"
    }
  }
])
D
db.employees.aggregate([
  {
    $match: { _id: 1 }
  },
  {
    $graphLookup: {
      from: "employees",
      startWith: "$_id",
      connectFromField: "_id",
      connectToField: "manager_id",
      as: "subordinates"
    }
  }
])
Attempts:
2 left
💡 Hint
Remember to start the graph lookup from the manager's _id and filter before the lookup.
📝 Syntax
intermediate
1:30remaining
Identify the syntax error in $graphLookup usage
Which option contains a syntax error in the $graphLookup stage?
MongoDB
db.collection.aggregate([
  {
    $graphLookup: {
      from: "collection",
      startWith: "$parent_id",
      connectFromField: "_id",
      connectToField: "parent_id",
      as: "descendants"
    }
  }
])
A{ $graphLookup: { from: "collection", startWith: "$parent_id", connectFromField: "_id", connectToField: "parent_id", as: "descendants" } }
B{ $graphLookup: { from: "collection", startWith: parent_id, connectFromField: "_id", connectToField: "parent_id", as: "descendants" } }
C $graphLookup: { from: "collection", startWith: "$parent_id", connectFromField: "_id", connectToField: "parent_id", as: "descendants" } }
D} } "stnadnecsed" :sa ,"di_tnerap" :dleiFoTtcennoc ,"di_" :dleiFmorFtcennoc ,"di_tnerap$" :htiWtrats ,"noitcelloc" :morf { :pukooLhparg$ {
Attempts:
2 left
💡 Hint
Check for missing commas between fields in the object.
❓ optimization
advanced
2:00remaining
Optimize recursive lookup to limit depth
You want to find all descendants of a node but limit recursion to 3 levels deep. Which $graphLookup option achieves this?
A{ $graphLookup: { from: "nodes", startWith: "$_id", connectFromField: "_id", connectToField: "parent_id", as: "descendants", maxDepth: "3" } }
B{ $graphLookup: { from: "nodes", startWith: "$_id", connectFromField: "_id", connectToField: "parent_id", as: "descendants", depthField: 3 } }
C{ $graphLookup: { from: "nodes", startWith: "$_id", connectFromField: "_id", connectToField: "parent_id", as: "descendants", maxDepth: 3 } }
D{ $graphLookup: { from: "nodes", startWith: "$_id", connectFromField: "_id", connectToField: "parent_id", as: "descendants", maxDepth: 0 } }
Attempts:
2 left
💡 Hint
maxDepth expects a number indicating maximum recursion depth.
🧠 Conceptual
advanced
1:30remaining
Understanding $graphLookup's connectFromField and connectToField
In a $graphLookup stage, what is the role of connectFromField and connectToField?
AconnectFromField is the field in the 'from' collection to match, connectToField is the field in the local collection to match against.
BconnectFromField is the field in the local collection to match, connectToField is the field in the 'from' collection to match against.
CconnectFromField is the field in the 'from' collection to match against, connectToField is the field in the 'from' collection to match.
DconnectFromField and connectToField are both fields in the local collection used for matching.
Attempts:
2 left
💡 Hint
Think about which collection is being searched and which is the starting point.
🔧 Debug
expert
2:30remaining
Why does this $graphLookup return an empty array?
Given the collection categories with documents having _id and parent_id, the following query returns an empty children array for _id: 10. Why? Query:
db.categories.aggregate([
  { $match: { _id: 10 } },
  { $graphLookup: {
      from: "categories",
      startWith: "$_id",
      connectFromField: "parent_id",
      connectToField: "_id",
      as: "children"
    }
  }
])
AThe 'as' field name 'children' is reserved and cannot be used.
BconnectFromField and connectToField are reversed; connectFromField should be '_id' and connectToField 'parent_id'.
CThe $match stage should come after $graphLookup, not before.
DstartWith should be a literal value 10, not '$_id'.
Attempts:
2 left
💡 Hint
Check which fields represent parent and child in the recursive relation.

Practice

(1/5)
1. What is the primary purpose of the $graphLookup stage in MongoDB aggregation?
easy
A. To create indexes on fields
B. To perform a simple filter on documents
C. To update multiple documents at once
D. To recursively search connected documents within the same collection

Solution

  1. Step 1: Understand the role of $graphLookup

    $graphLookup is designed to recursively find related documents by following references within the same collection, useful for hierarchical data.
  2. Step 2: Compare with other options

    Options B, C, and D describe other MongoDB operations unrelated to recursive lookup.
  3. Final Answer:

    To recursively search connected documents within the same collection -> Option D
  4. Quick Check:

    $graphLookup = recursive search [OK]
Hint: Remember $graphLookup is for recursive connected data search [OK]
Common Mistakes:
  • Confusing $graphLookup with $match filtering
  • Thinking $graphLookup updates documents
  • Assuming $graphLookup creates indexes
2. Which of the following is the correct syntax to start a $graphLookup stage in a MongoDB aggregation pipeline?
easy
A. {"$graphLookup": {"from": "employees", "startWith": "$managerId", "connectFromField": "_id", "connectToField": "managerId", "as": "reportingHierarchy"}}
B. {"$graphLookup": {"from": "employees", "startWith": "$managerId", "connectFromField": "managerId", "connectToField": "_id", "as": "reportingHierarchy"}}
C. {"$graphLookup": {"from": "employees", "startWith": "managerId", "connectFromField": "_id", "connectToField": "managerId", "as": "reportingHierarchy"}}
D. {"$graphLookup": {"from": "employees", "startWith": "$id", "connectFromField": "managerId", "connectToField": "_id", "as": "reportingHierarchy"}}

Solution

  1. Step 1: Identify correct field references

    In $graphLookup, startWith uses the field to start recursion, usually a reference like "$managerId". The connectToField is the field in the foreign documents to match against the start value, here "_id". The connectFromField is the field in the foreign document used for the next recursion, here "managerId".
  2. Step 2: Match syntax with options

    {"$graphLookup": {"from": "employees", "startWith": "$managerId", "connectFromField": "managerId", "connectToField": "_id", "as": "reportingHierarchy"}} correctly uses startWith: "$managerId", connectFromField: "managerId", and connectToField: "_id". Others swap these or use incorrect field names.
  3. Final Answer:

    {"$graphLookup": {"from": "employees", "startWith": "$managerId", "connectFromField": "managerId", "connectToField": "_id", "as": "reportingHierarchy"}} -> Option B
  4. Quick Check:

    Correct field mapping = {"$graphLookup": {"from": "employees", "startWith": "$managerId", "connectFromField": "managerId", "connectToField": "_id", "as": "reportingHierarchy"}} [OK]
Hint: Match startWith with $field, connectToField with foreign _id [OK]
Common Mistakes:
  • Swapping connectFromField and connectToField
  • Missing $ in startWith field
  • Using wrong field names for connections
3. Given the following collection categories with documents:
{"_id": 1, "name": "Electronics", "parent": null}
{"_id": 2, "name": "Computers", "parent": 1}
{"_id": 3, "name": "Laptops", "parent": 2}

What will be the result of this aggregation?
[ { "$graphLookup": { "from": "categories", "startWith": "$parent", "connectFromField": "parent", "connectToField": "_id", "as": "ancestors" } } ]

for the document with _id: 3?
medium
A. An array 'ancestors' containing documents with _id 2 and 1
B. An empty array 'ancestors'
C. An array 'ancestors' containing only document with _id 1
D. A syntax error due to incorrect $graphLookup usage

Solution

  1. Step 1: Understand the recursive lookup

    Starting from the document with _id 3, startWith uses its parent field which is 2. Then it finds documents where _id matches 2, then recursively finds parents of 2, which is 1.
  2. Step 2: Trace the ancestors found

    The recursion finds documents with _id 2 and then _id 1, so the 'ancestors' array contains both documents.
  3. Final Answer:

    An array 'ancestors' containing documents with _id 2 and 1 -> Option A
  4. Quick Check:

    Recursive parents = [2, 1] [OK]
Hint: Trace startWith field value and follow connectToField recursively [OK]
Common Mistakes:
  • Assuming only direct parent is returned
  • Confusing connectFromField and connectToField
  • Expecting syntax error incorrectly
4. Consider this aggregation pipeline snippet:
{ "$graphLookup": { "from": "employees", "startWith": "$managerId", "connectFromField": "managerId", "connectToField": "_id", "as": "team" } }

Why might this pipeline fail or return empty results when run on an employee document with no managerId field?
medium
A. Because as field name is invalid
B. Because connectFromField and connectToField are swapped
C. Because startWith is null or missing, recursion cannot start
D. Because from collection does not exist

Solution

  1. Step 1: Check the startWith field value

    If the document has no managerId field, startWith evaluates to null or undefined, so the recursion has no starting point.
  2. Step 2: Understand impact on results

    Without a valid start value, $graphLookup returns an empty array for 'team' because it cannot find connected documents.
  3. Final Answer:

    Because startWith is null or missing, recursion cannot start -> Option C
  4. Quick Check:

    Missing startWith value = empty results [OK]
Hint: Ensure startWith field exists and is not null [OK]
Common Mistakes:
  • Thinking connectFromField/connectToField swap causes empty results
  • Assuming 'as' field name causes failure
  • Ignoring missing 'from' collection errors
5. You have a collection employees where each document has _id and managerId. You want to find all employees under a manager recursively, including the manager. Which $graphLookup configuration correctly achieves this?
hard
A. {"$graphLookup": {"from": "employees", "startWith": "$_id", "connectFromField": "_id", "connectToField": "managerId", "as": "team"}}
B. {"$graphLookup": {"from": "employees", "startWith": "$managerId", "connectFromField": "managerId", "connectToField": "_id", "as": "team"}}
C. {"$graphLookup": {"from": "employees", "startWith": "$_id", "connectFromField": "managerId", "connectToField": "_id", "as": "team"}}
D. {"$graphLookup": {"from": "employees", "startWith": "$managerId", "connectFromField": "_id", "connectToField": "managerId", "as": "team"}}

Solution

  1. Step 1: Define the recursion direction

    To find all employees under a manager, start with the manager's _id. Then find employees whose managerId matches this _id, recursively.
  2. Step 2: Match fields in $graphLookup

    startWith should be $_id (the manager's id). connectToField is managerId (field in employees to match), and connectFromField is _id (field to match against for next level).
  3. Step 3: Verify options

    {"$graphLookup": {"from": "employees", "startWith": "$_id", "connectFromField": "_id", "connectToField": "managerId", "as": "team"}} matches this logic exactly. {"$graphLookup": {"from": "employees", "startWith": "$_id", "connectFromField": "managerId", "connectToField": "_id", "as": "team"}} swaps connectFromField and connectToField incorrectly. The options starting with $managerId are wrong for this use case.
  4. Final Answer:

    {"$graphLookup": {"from": "employees", "startWith": "$_id", "connectFromField": "_id", "connectToField": "managerId", "as": "team"}} -> Option A
  5. Quick Check:

    Start with manager _id, connectFromField = _id, connectToField = managerId = {"$graphLookup": {"from": "employees", "startWith": "$_id", "connectFromField": "_id", "connectToField": "managerId", "as": "team"}} [OK]
Hint: Start with manager _id, connectFromField = _id, connectToField = managerId [OK]
Common Mistakes:
  • Swapping connectFromField and connectToField
  • Starting with $managerId instead of $_id
  • Confusing direction of recursion
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