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:
preludefor 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.