How to Use $graphLookup in Aggregation in MongoDB
Use the
$graphLookup stage in a MongoDB aggregation pipeline to perform recursive searches on documents within a collection. It lets you find connected data by specifying a starting point, the field to match, and how to traverse the graph-like structure. This is useful for hierarchical or linked data queries.Syntax
The $graphLookup stage has several key parts:
- from: The collection to search.
- startWith: Expression to specify the starting value(s) for the recursion.
- connectFromField: Field name in the
fromcollection to follow. - connectToField: Field name in the
fromcollection to match withconnectFromField. - as: Name of the output array field to store matched documents.
- maxDepth (optional): Limits recursion depth.
- depthField (optional): Adds a field to show recursion depth.
json
{
$graphLookup: {
from: "collectionName",
startWith: "<expression>",
connectFromField: "fieldName",
connectToField: "fieldName",
as: "outputArray",
maxDepth: <number>, // optional
depthField: "depthFieldName" // optional
}
}Example
This example demonstrates how to find all subordinates of an employee recursively in an employees collection where each document has an _id and a manager_id field.
mongodb
db.employees.aggregate([
{
$graphLookup: {
from: "employees",
startWith: "$_id",
connectFromField: "_id",
connectToField: "manager_id",
as: "subordinates"
}
}
])Output
[
{
_id: 1,
name: "Alice",
manager_id: null,
subordinates: [
{ _id: 2, name: "Bob", manager_id: 1 },
{ _id: 3, name: "Charlie", manager_id: 2 },
{ _id: 4, name: "David", manager_id: 2 }
]
},
{
_id: 2,
name: "Bob",
manager_id: 1,
subordinates: [
{ _id: 3, name: "Charlie", manager_id: 2 },
{ _id: 4, name: "David", manager_id: 2 }
]
},
{
_id: 3,
name: "Charlie",
manager_id: 2,
subordinates: []
},
{
_id: 4,
name: "David",
manager_id: 2,
subordinates: []
}
]
Common Pitfalls
Common mistakes when using $graphLookup include:
- Not specifying the correct
connectFromFieldandconnectToField, which breaks the recursion. - Forgetting to use
startWithproperly, causing no results or infinite recursion. - Not limiting recursion depth with
maxDepthwhen needed, which can cause performance issues. - Using
$graphLookupon very large collections without indexes on the fields used for connection, leading to slow queries.
Example of a wrong and right usage:
json
// Wrong: Missing startWith { $graphLookup: { from: "employees", connectFromField: "_id", connectToField: "manager_id", as: "subordinates" } } // Right: Include startWith { $graphLookup: { from: "employees", startWith: "$_id", connectFromField: "_id", connectToField: "manager_id", as: "subordinates" } }
Quick Reference
Tips for using $graphLookup effectively:
- Always index the fields used in
connectFromFieldandconnectToFieldfor better performance. - Use
maxDepthto avoid deep or infinite recursion. - Use
depthFieldto track recursion levels if needed. - Remember
startWithcan be a field path or an expression.
Key Takeaways
Use $graphLookup to perform recursive searches within a collection based on linked fields.
Specify from, startWith, connectFromField, connectToField, and as to configure the recursion.
Always set maxDepth to limit recursion depth and improve performance.
Ensure proper indexes exist on fields used for connecting documents.
Use depthField to track recursion depth if you need to analyze levels.