Explicit execution
Fluent traversals can be wrapped into a FluentGraphStatement and passed to the session:
// A "dummy", non-connected traversal source that is not meant to be iterated directly, but instead
// serves as the basis to build fluent statements:
import static com.datastax.dse.driver.api.core.graph.DseGraph.g;
GraphTraversal<Vertex, Vertex> traversal = g.V().has("name", "marko");
FluentGraphStatement statement = FluentGraphStatement.newInstance(traversal);
GraphResultSet result = session.execute(statement);
for (GraphNode node : result) {
System.out.println(node.asVertex());
}
Creating fluent statements
Factory method
As shown above, FluentGraphStatement.newInstance creates a statement from a traversal directly.
The default implementation returned by the driver is immutable; if you call additional methods on the statement – for example to set options – each method call will create a new copy:
FluentGraphStatement statement = FluentGraphStatement.newInstance(traversal);
FluentGraphStatement statement2 = statement.setTimeout(Duration.ofSeconds(10));
assert statement2 != statement;
Immutability is good because it makes statements inherently thread-safe: you can share them in your application and access them concurrently without any risk.
On the other hand, it means a lot of intermediary copies if you often call methods on your statements. Modern VMs are normally good at dealing with such short-lived objects, but if you’re worried about the performance impact, consider using a builder instead.
Note: contrary to driver statements, Tinkerpop’s GraphTraversal
is mutable and therefore not
thread-safe. This is fine if you just wrap a traversal into a statement and never modify it
afterwards, but be careful not to share traversals and modify them concurrently.
Builder
Instead of creating a statement directly, you can pass your traversal to
FluentGraphStatement.builder, chain method calls to set options, and finally call build()
:
FluentGraphStatement statement1 =
FluentGraphStatement.builder(traversal)
.withTimeout(Duration.ofSeconds(10))
.withIdempotence(true)
.build();
The builder implementation is mutable: every method call returns the same object, only one builder instance will be created no matter how many methods you call on it. As a consequence, the builder object is not thread-safe.
You can also initialize a builder from an existing statement: it will inherit all of its options.
FluentGraphStatement statement2 =
FluentGraphStatement.builder(statement1).withTimeout(Duration.ofSeconds(20)).build();
assert statement2.getTraversal().equals(statement1.getTraversal());
assert statement2.getTimeout().equals(Duration.ofSeconds(20)); // overridden by the builder
assert statement2.isIdempotent(); // because statement1 was
Batching traversals
BatchGraphStatement allows you to execute multiple mutating traversals in the same transaction. Like other types of statements, it is immutable and thread-safe, and can be created either with a factory method or a builder:
GraphTraversal<Vertex, Vertex> traversal1 = g.addV("person").property("name", "batch1").property("age", 1);
GraphTraversal<Vertex, Vertex> traversal2 = g.addV("person").property("name", "batch2").property("age", 2);
// Each method call creates a copy:
BatchGraphStatement batch1 = BatchGraphStatement.newInstance()
.addTraversal(traversal1)
.addTraversal(traversal2);
// Uses a single, mutable builder instance:
BatchGraphStatement batch2 = BatchGraphStatement.builder()
.addTraversal(traversal1)
.addTraversal(traversal2)
.build();
Traversal batches are only available with DSE 6.0 or above.
Prepared statements
At the time of writing (DSE 6.0), prepared graph statements are not supported yet; they will be added in a future version.
See also the parent page for topics common to all fluent traversals.