Rust Quick Start

Add the crate with the features you need (Installation lists them all):

[dependencies]
graphersal = { version = "0.1", features = ["script", "io", "display"] }
  • script: the Gremlin DSL as text, the same language as the CLI, the playground and Python;
  • io: GraphSON and GraphML files;
  • display: results rendered as tables;
  • persist: snapshots, the journal and the Store on disk.

The code on this page is the example crates/graphersal/examples/quick_start.rs; run it with cargo run -p graphersal --example quick_start --features script,io,display.

Read

use graphersal::prelude::* brings everything a query needs. A graph is shared behind a lock: a read lock gives a traversal source, the steps are methods, and a terminal (to_list, next, iterate) runs the traversal.

    // The TinkerPop "modern" sample graph: 4 people, 2 pieces of software, 6 edges.
    let graph = GraphSource::tinkerpop_modern();

    // A read lock gives a traversal source `g`; the traversal is built step by step and run by
    // its terminal (`to_list`, `next`, `iterate`).
    let lock = graph.read();
    let friends = lock
        .traversal()
        .v(None)
        .has("name", "marko")
        .out("knows")
        .values("name")
        .to_list()?;
    println!("marko knows {friends:?}"); // marko knows ["josh", "vadas"]
    drop(lock);

v(None) starts at every vertex; v("1") or v(vec!["1", "2"]) at given ids. The Rust names are the snake_case names of the DSL, with a trailing underscore where Rust needs one (as_, in_).

Write

Writes take the write lock and traversal_mut(). A traversal is one unit: it commits when it succeeds and is rolled back completely when any step fails. Anonymous traversals start with __::.

    // Writes take the write lock. Every traversal is one unit: it commits when it succeeds and
    // leaves nothing behind when it fails.
    graph
        .write()
        .traversal_mut()
        .v(None)
        .has("name", "marko")
        .add_e("knows")
        .to_by(__::add_v("person").property("name", "ann"))
        .iterate()?;
    let people = graph
        .read()
        .traversal()
        .v(None)
        .has_label("person")
        .count()
        .next()?;
    println!("people: {people:?}"); // people: Some(5)

Several traversals become one unit with Transactional::transaction; a dry run shows the changes a closure would make without keeping them (Transactions).

The DSL from Rust

With the script feature a query can also be text, for example one a user typed. eval_value returns the result as a script value, eval renders it for display:

    // The same queries as text, in the Gremlin DSL (feature `script`): what the CLI, the
    // playground and Python run. Both spellings work: `has_label` and `hasLabel`.
    let graph = Arc::new(graph);
    let names = graphersal::script::eval_value(
        graph.clone(),
        r#"g.V().has("name", "marko").out("knows").values("name").order().toList()"#,
    )?;
    println!("{names}"); // ["ann", "josh", "vadas"]

    // `eval` renders the result for display: JSON lines, a table with feature `display`.
    let table = graphersal::script::eval(
        graph,
        r#"g.V().hasLabel("software").valueMap("name", "lang")"#,
    )?;
    println!("{table}");

These two helpers allow everything. For a query you did not write, use script::eval_value_with_limits with an Authorizer such as AccessPolicy::read_only() and ScriptLimits (Permissions, Resource Limits).

Files and samples

With the io feature:

        let modern = GraphSource::tinkerpop_modern(); // the samples: also file_tree(), large_110k()
        modern.read().traversal().export_graphson(path)?; // GraphSON 3.0, TinkerPop's format
        let copy = GraphSource::from_graphson(path)?; // also from_graphml, from_file
        let two = copy
            .read()
            .traversal()
            .v(vec!["1", "2"])
            .values("name")
            .to_list()?;
        println!("{two:?}"); // ["marko", "vadas"]

Where to go from here

  • the API reference on docs.rs: prelude for queries, the topic modules (schema, changes, auth, catalog, exec, profile, storage, persist) for integration;
  • Transactions: units, dry runs, change capture and commit hooks;
  • Schemas;
  • Persistence Overview: a graph on disk;
  • Custom Storages: run the engine on your own storage.