Collect Step

The collect step gathers the IDs of all elements from a traversal into a specified Rust collection type (e.g., Vec, HashSet, BTreeSet). This is a terminal operation that consumes the walker and returns the populated collection.

Collect step diagram showing elements flowing into the step and a Rust collection of IDs as the output

In this diagram:

  • Input Elements: The walker starts with elements A, B, C.
  • The .collect::<Vec<_>>() step processes the stream and consumes the walker. The type parameter (Vec<_>) specifies the desired collection type.
  • Returns: Vec<ID>: The step returns a Rust Vec containing the unique identifiers (IDs) of the elements that were processed ([ID(A), ID(B), ID(C)]).
  • Terminates Walker: This step ends the Graph API walker chain.

Syntax

walker.collect::<C>()

Where C is the collection type you want to gather results into.

Parameters

This step takes no parameters, but uses a type parameter to specify the collection type.

Return Value

Returns a collection of type C where C implements FromIterator.

Examples

Collecting into a Vec

The most common use case is collecting elements into a Vec:

    // Collect results into a Vec
    // Use the person() index method to get all Person vertices
    let person_vertices: Vec<_> = graph
        .walk()
        .vertices(Vertex::person()) // Type-safe vertex lookup by label
        .collect::<Vec<_>>();

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

Collecting Unique Values

You can collect into a HashSet to get unique values:

    // Collect into a HashSet for unique elements
    let unique_names: HashSet<String> = graph
        .walk()
        .vertices(Vertex::person())
        // Use map to extract properties from each person
        .map(|person, _| {
            // Use projection to access Person methods in a type-safe way
            person
                .project::<Person<_>>() // Project to Person type
                .map(|p| p.name().to_string()) // Use accessor method from projection
                .unwrap_or_else(|| "Unknown".to_string())
        })
        .collect::<HashSet<String>>();

    println!("Found {} unique person names", unique_names.len());

Collecting into an Range Set

Use a BTreeSet when you need range unique values:

    // Collect into a BTreeSet for range unique elements
    let range_ages: BTreeSet<u8> = graph
        .walk()
        .vertices(Vertex::person())
        // Use filter_person() to work exclusively with Person vertices (no closure needed)
        .filter_person() // Label-based type filter with no closure
        // Extract age from each Person vertex
        .map(|person, _| {
            // Use projection to access Person methods in a type-safe way
            person
                .project::<Person<_>>() // Project to Person type
                .map(|p| p.age()) // Use age() accessor method
                .unwrap_or(0)
        })
        .collect::<BTreeSet<u8>>();

    // Print ages in ascending order (BTreeSet maintains order)
    println!("Person ages (range): {:?}", range_ages);

Best Practices

  • Use limit before collect when working with large graphs to control memory usage
  • Choose the right collection type for your needs:
    • Vec: When order matters and duplicates are acceptable
    • HashSet: When you need unique elements and don't care about order
    • BTreeSet: When you need unique elements in a specific order

Common Use Cases

  • Result accumulation: Collecting all vertices meeting specific criteria
  • Set operations: Gathering unique elements via HashSet for later processing
  • Ordered results: Using BTreeSet when elements need to be in a specific order
  • Custom collections: Feeding traversal results into specialized data structures