Default Context
The push_default_context
step provides a simplified way to track vertex and edge information during traversal, without
having to define custom context types. It automatically captures the current vertex or edge to make it available in
downstream steps.
In this diagram:
- An Input Stream contains elements A and B.
- The
.push_default_context()
step is applied. - In the Output Stream, each element is paired with a context that automatically contains that specific element.
- Element A is paired with
Context: A
. - Element B is paired with
Context: B
.
- Element A is paired with
- This shows how the default context dynamically reflects the current element being processed.
Syntax
walker.push_default_context()
Parameters
This step takes no parameters.
Return Value
Returns a new walker with the default context added, preserving the current traversal position.
Examples
Tracking Relationships
Use default context to describe relationships between people:
pub fn default_context_example<G>(graph: &G, bryn_id: G::VertexId, julia_id: G::VertexId)
where
G: Graph<Vertex = Vertex, Edge = Edge>,
{
// Use default context to access vertex information directly from prior in the traversal
let knows = graph
.walk()
.vertices_by_id(vec![bryn_id, julia_id])
.push_default_context()
.edges(EdgeSearch::scan().outgoing())
.filter_follows()
.head()
.map(|target_vertex, ctx| {
// Access source person name from context
let source_name = match ctx.vertex() {
Vertex::Person { name, .. } => name.clone(),
_ => "Unknown".to_string(),
};
// Access target person name from vertex
let person = target_vertex.project::<Person<_>>().unwrap();
format!("{} knows {}", source_name, person.name())
})
.collect::<Vec<_>>();
// Check the results
println!("Relationships found:");
for relationship in &knows {
println!("- {}", relationship);
}
}
Working with Edge Properties
Combine edge properties with source vertex information:
pub fn edge_properties_example<G>(graph: &G, person_id: G::VertexId)
where
G: Graph<Vertex = Vertex, Edge = Edge>,
{
// Find relationships with metadata
let relationships = graph
.walk()
.vertices_by_id(vec![person_id])
.push_default_context()
.edges(EdgeSearch::scan().outgoing())
.map(|edge, ctx| {
// Get the source person's name
let source_name = match ctx.vertex() {
Vertex::Person { name, .. } => name.clone(),
_ => "Unknown".to_string(),
};
// Format based on edge type
match edge.weight() {
Edge::Follows => {
format!("{} follows someone", source_name)
}
Edge::Created => {
format!("{} created something", source_name)
}
Edge::Liked { timestamp } => {
format!("{} liked something at {}", source_name, timestamp)
}
Edge::Commented { timestamp } => {
format!("{} commented on something at {}", source_name, timestamp)
}
}
})
.collect::<Vec<_>>();
println!("Person relationships with metadata:");
for rel in relationships {
println!("- {}", rel);
}
}
Default Context Structure
The default context automatically tracks:
- For vertices: The current vertex reference
- For edges: Both the source and target vertex references
Accessing Default Context
You can access the context in subsequent steps like this:
// After pushing default context
walker
.push_default_context()
.map(|current_element, ctx| {
// Access vertex from context
let context_vertex = ctx.vertex();
// Work with the context vertex
// ...
})
Best Practices
- Use default context for simple element tracking rather than creating custom context types
- Chain default contexts in multi-step traversals to maintain element history
- Access context values using the appropriate type-safe methods (e.g.,
ctx.vertex()
,ctx.edge()
) - Consider default context before writing complex custom context functions for basic traversals
Common Use Cases
- Relationship description: Building natural language descriptions (e.g., "Person A knows Person B")
- Path tracking: Recording the sequence of vertices and edges in a traversal
- Element comparison: Comparing properties between current and previous elements
- Data collection: Gathering information from connected elements in the graph