The ‘$graphLookup‘ operator in the MongoDB aggregation framework can be used to perform recursive search on hierarchical data. This operator searches for documents recursively in a collection or view using the adjacency list model. The operator takes the following parameters:
- ‘from‘: The collection or view to perform the recursive search on.
- ‘startWith‘: The value to start the recursive search with.
- ‘connectFromField‘: The field in the ‘from‘ collection or view that contains the reference to the parent document.
- ‘connectToField‘: The field in the input documents that contains the reference to the child document.
- ‘as‘: The output array field that contains the matching documents.
- ‘maxDepth‘: The maximum recursion depth. If set to a positive integer, the operator will stop the search after that many recursive levels.
- ‘restrictSearchWithMatch‘: An optional query expression that limits the documents processed by the $graphLookup operation.
Here is an example of how to use the ‘$graphLookup‘ operator to traverse a tree structure in a collection called ‘categories‘:
db.categories.aggregate([
{
$graphLookup: {
from: "categories",
startWith: "$_id",
connectFromField: "_id",
connectToField: "parentId",
as: "subcategories",
maxDepth: 5
}
}
])
In this example, we are traversing a tree structure where each document in the ‘categories‘ collection has a ‘parentId‘ field referencing its parent document. We are starting the search with the ‘_id‘ field of the input documents, and creating an output array field called ‘subcategories‘ that contains all matching documents up to a depth of 5.
The ‘$graphLookup‘ operator can return a lot of duplicate documents, especially in cases where circular references exist. To handle this, we can use the ‘$group‘ stage to remove duplicates, like this:
db.categories.aggregate([
{
$graphLookup: {
from: "categories",
startWith: "$_id",
connectFromField: "_id",
connectToField: "parentId",
as: "subcategories",
maxDepth: 5
}
},
{
$unwind: "$subcategories"
},
{
$group: {
_id: "$subcategories._id",
name: { $first: "$subcategories.name" },
parentId: { $first: "$subcategories.parentId" },
// any other fields you want to include
}
},
{
$group: {
_id: "$_id",
name: { $first: "$name" },
parentId: { $first: "$parentId" },
subcategories: { $push: "$$ROOT" },
}
}
])
In this example, we first use the ‘$graphLookup‘ operator to create an array of subcategories for each input document. Then, we use the ‘$unwind‘ stage to flatten the ‘subcategories‘ array. We group the flattened documents by ‘_id‘, taking the first value of the ‘name‘ and ‘parentId‘ fields (since they should be the same for all documents with the same ‘_id‘). Finally, we group the documents by ‘_id‘ again, creating an array of ‘subcategories‘ for each document.
Overall, the ‘$graphLookup‘ operator can be a powerful tool for performing recursive searches on hierarchical data in MongoDB. However, it can be complex to use and can have performance issues if used improperly. It is important to carefully consider your use case and data model before using this operator.