Vertices Step

The vertices step starts a traversal by selecting an initial set of vertices from the graph based on specified criteria (e.g., using an index or a scan). This step initiates the stream of elements for subsequent walker operations.

Vertices step diagram showing initial selection of vertices based on criteria

In this diagram:

  • The Conceptual Graph Vertices represent the available vertices in the graph (A: Person, B: Product, C: Person, D: Review).
  • The graph.walk().vertices(Vertex::person()) step is applied, using criteria (like a label index) to select only "Person" vertices.
  • The Output Stream contains only the selected vertices A and C, which match the criteria and become the initial elements for the rest of the traversal.

Syntax

graph.walk().vertices(search_criteria)

Where search_criteria is a VertexSearch object or a predefined search from an index.

Parameters

  • search_criteria: A VertexSearch object that defines the criteria for selecting vertices

Return Value

Returns a new walker positioned at the vertices matching the search criteria.

Examples

Full Scan

When you need to find all vertices in a graph:

    // Scan all vertices in the graph
    // This performs a full graph scan, which can be expensive for large graphs
    let all_vertices = graph
        .walk()
        .vertices(VertexSearch::scan())
        .collect::<Vec<_>>();

    println!("Found {} total vertices in the graph", all_vertices.len());

Using a Label Index

For more efficient queries, use label-based indexes:

    // Use a label-based index for more efficient lookups
    // This narrows the search to only person vertices
    let people = graph.walk().vertices(Vertex::person()).collect::<Vec<_>>();

    println!("Found {} person vertices", people.len());

Property-Based Filtering

Find vertices based on their properties:

    // Use property-based filtering
    // This finds vertices with a specific property value
    let people_named_bob = graph
        .walk()
        .vertices(VertexSearch::scan())
        .filter_person() // First filter by vertex type
        .filter_by_person(|person, _| {
            // Then use type-safe accessor methods
            person.name() == "Julia"
        })
        .collect::<Vec<_>>();

    println!("Found {} people named Bob", people_named_bob.len());

Combined Filtering

Chain multiple conditions for complex queries:

    // Combine filtering to find young people
    // Filter after retrieval when specialized indexes aren't available
    let young_people = graph
        .walk()
        .vertices(Vertex::person()) // Get all Person vertices
        .filter_by_person(|person, _| {
            // Use type-safe accessor methods
            person.age() < 30 // Find people under 30
        })
        .collect::<Vec<_>>();

    println!("Found {} people under age 30", young_people.len());

Best Practices

  • Start with the most specific index when possible instead of scanning all vertices
  • Use specialized indexes for frequently queried properties to improve performance
  • Combine multiple search criteria to narrow results early in the traversal
  • For ordered results, rely on range indexes rather than sorting later

Common Use Cases

  • Entity retrieval: Finding vertices of a specific type (e.g., all users, products, etc.)
  • Initial selection: Starting traversals by selecting entry points based on criteria
  • Filtered starting sets: Beginning with a targeted subset that matches complex conditions
  • Index-driven queries: Leveraging custom indexes for specialized lookups based on specific properties