Let's discuss another aggregation stage, $graphLookup. $graphLookup allows us to recursively traverse a graph structure represented in documents. $graphLookup has the following form. Let's go over the parameters. Since it's a lookup operation, we specify the collection where we want to perform the graph search using the from field. We have to specify startWith, the initial field that we should startWith in the current document. This will be used to initially start the matching in subsequent recursive travel. startWith must be an expression. connectToField and connectFromField, which are the fields that we are going to link using the field value of the connectFromField to query against the connectToField in a recursive fashion. On the first operation, startWith will compare its value to the value of the field in connectToField. These are specified strings, not as field path expressions. As, determines the name of the field that will hold the result. And just like lookup, it will be an array. Empty if there were no successful matches. And then we have our optional fields. maxDepth, determines how deep we want to go on a recursive search. depthField is a name that we provide, which will be assigned the depth, the graphLookup had to go in order to find that entry. And lastly, we have restrictSearchWithMatch, where we can specify a filter to be applied on each of the matching recursive lookup documents. So, imagine we have a collection with the following documents. that we would like to explore. And this is a visualization of the graph they would form, with nodes and edges. We'll specify a startWith of node, which identifies the field to begin the search from. For our connectFromField, we'll specify the connections field. This will compare the value, or values in this case because it is an array, to the connectToField, and this will match the document with a value of four for node, because we specify node as the connecToField. So node four connects to one, two, and five. We've already traversed from 1-4, so that's not necessary. Node two connects to node four and five. We don't need to visit node four, so we visit node five. Node five, connects to nodes two, three, and four. We've already visited nodes two and four now, so we go to node three. Node three only connects to node five, which has already been traversed, so we end there. Let's look at that in action. First, let's consider our nodes. Let's go ahead and construct your aggregation. We use a mass stage before graphLookup, so we can see the same output as what the slide showed. We specify graphToFrom, the name of the collection. Remember, it doesn't have to be the same collection we're aggregating over, but the collection to from can't be shared, just like the lookup stage. We specify the node to startwith, connections as a connectFromField, and node as a connectToField. Lastly, we specified as, as demo. And the results are just as we expected. Looking at the Demo field, we can see that the first entry at the bottom was Node one, which connects to node four. The next century is node four, which connects to one, two, and five. The next is two, which connects to four and five. Then we have node five, which connects to two, three, and four. And lastly, we have node three which connects to node five. Now, we've already visited every single node. So here, the graphLookup would stop. Let's look in a more concrete example. Let's say I'm on vacation in Germany, and I decide, I'd like to catch a flight somewhere new on Lufthansa Airlines. I don't like to sit for a long time, so I only want a maximum of two layovers. Let's look at the schema. Here's a document where the airline name is Lufthansa and the source airport is TXL, which is in Berlin. We have a good starting point. So, let's build our aggregation. ToFrom will specify air routes. We'll start with the source airport which is TXL. Our ConnectFrom field will be the destination airport and our connectToField will be the source airport. Let's go over this before we run it. We'll go ahead and restrict possible starting points to those that leave from Berlin, airport code TXL, and are operated by Lufthansa. In the graphLookup stage, I'll specify air _routes to from. startWith is the value of the source airport field which we know as TXL. And then we recursively search, connecting destination airports of a source airports with a max depth of two. I've included a depth field and called it hops, so that I can filter these results later. I restrict the search to only mesh routes operated by Lufthansa. In the ad field stage, I filter the quick trips array. I created with a graphic upstages to only destinations that are two hops away. I may as well make the most of my vacation. Let's take a look. And based on the results, it looks like I have a ton of options. Let's summarize. Graph Lookup requires to run on a primary short in a shorter environment, because it can only look up from other collections in the same database, and those collections can't be shredded. Specifying allowDiskiscoversTrue has no effect on the graphLookupStage. If it exceeds 100 megabytes of memory, it will fail. And failing to specify a maxDepth can result in a very long running Operation depending on the graph-like structure and size of the data in your collection.