Walker Overview
Walkers are the central concept in Graph API traversals. They provide a fluent interface for exploring and manipulating graph data.
What are Walkers?
A walker represents a traversal through a graph. It consists of:
- A current position in the graph (vertices or edges)
- Context data that can be carried along the traversal
- A sequence of steps that define the traversal path
Walkers use a builder pattern where each step returns a new walker with the accumulated operations.
How Walkers Work
- Start with an empty walker using
graph.walk()
- Chain steps to define your traversal:
.vertices().edges().tail()
- End with a terminal operation:
.collect()
,.first()
,.count()
, etc.
Each step in the chain modifies the traversal in a specific way, moving to different elements, filtering, or collecting data.
Types of Walkers
The Graph API has two main types of walkers:
- Vertex Walkers: Traverse vertex elements
- Edge Walkers: Traverse edge elements
Some operations switch between these types. For example, .edges()
converts a vertex walker to an edge walker, while
.head()
and .tail()
convert an edge walker to a vertex walker.
Walker States
A walker can be in one of several states:
- Empty: No elements to traverse (starting state)
- Active: Contains elements to traverse
- Terminal: Has performed its final operation
Creating Walkers
You create a walker by calling the walk()
method on a graph:
let walker = graph.walk();
This returns an empty walker that can be used to start your traversal.
Starting Traversals
There are several ways to populate a walker with initial elements:
// Start with all vertices
graph.walk().vertices(VertexSearch::scan())
// Start with specific vertex IDs
graph.walk().vertices_by_id(vec![vertex_id1, vertex_id2])
// Start with vertices matching criteria
graph.walk().vertices(VertexSearch::scan().with_label(Person::label()))
Walker Flow Control
Walkers provide several ways to control the traversal flow:
- Filtering: Keep only elements matching a condition
- Limiting: Restrict the number of elements processed
- Branching: Create sub-traversals that explore different paths
- Early Termination: Stop traversal after finding a match
Example Walker Traversals
Basic Traversal
// Find all Project vertices created by a Person
let _results = graph
.walk()
.vertices(Vertex::person()) // Start with all Person vertices
.edges(Edge::created()) // Follow "Created" edges
.tail() // Move to the target vertices (Projects)
.collect::<Vec<_>>(); // Collect the Project vertices
Multi-Step Traversal
// Find all people who follow someone who created a project
let _results = graph
.walk()
.vertices(Vertex::person()) // Start with all Person vertices
.edges(Edge::follows()) // Follow "follows" edges
.tail() // Move to the followed person
.edges(Edge::created()) // Find "created" edges from these people
.tail() // Move to the Project vertices
.collect::<Vec<_>>(); // Collect results
Traversal with Detour
// For each person, find the projects they created
let _results = graph
.walk()
.vertices(Vertex::person()) // Start with all Person vertices
.detour(|person_walker| {
// For each person, collect the projects they created
person_walker
.edges(Edge::created()) // Follow "created" edges
.tail() // Move to the target (projects)
.take(1) // Only need one match to qualify
})
// Continue with original person vertices that have created projects
.collect::<Vec<_>>(); // Collect results
Next Steps
To learn more about specific walker steps, see the Walker Steps documentation.