The driver depends on Apache TinkerPop™, a graph computing framework that provides a fluent API to build Gremlin traversals. This allows you to write your graph requests directly in Java, like you would in a Gremlin-groovy script:
// How this is initialized will depend on the execution model, see details below GraphTraversalSource g = ... GraphTraversal<Vertex, Vertex> traversal = g.V().has("name", "marko");
There are two ways to execute fluent traversals:
session.execute
;The following apply regardless of the execution model:
At the time of writing (DSE 6.0 / driver 4.0), some types of queries cannot be executed through the fluent API:
You'll have to use the script API for those use cases.
Before sending a fluent graph statement over the network, the driver serializes the Gremlin traversal into a byte array. Traversal serialization happens on the client thread, even in asynchronous mode. In other words, it is done on:
session.execute
or session.executeAsync
for explicit execution;In practice, this shouldn‘t be an issue, but we’ve seen it become problematic in some corner cases of our performance benchmarks: if a single thread issues a lot of session.executeAsync
calls in a tight loop, traversal serialization can dominate CPU usage on that thread, and become a bottleneck for request throughput.
If you believe that you're running into that scenario, start by profiling your application to confirm that the client thread maxes out its CPU core; to solve the problem, distribute your session.executeAsync
calls onto more threads.
Gremlin can be extended with domain specific languages to make traversals more natural to write. For example, considering the following query:
g.V().hasLabel("person").has("name", "marko"). out("knows").hasLabel("person").has("name", "josh");
A “social” DSL could be written to simplify it as:
socialG.persons("marko").knows("josh");
TinkerPop provides an annotation processor to generate a DSL from an annotated interface. This is covered in detail in the TinkerPop documentation.
Once your custom traversal source is generated, here's how to use it:
// Non-connected source for explicit execution: SocialTraversalSource socialG = DseGraph.g.getGraph().traversal(SocialTraversalSource.class); // Connected source for implicit execution: SocialTraversalSource socialG = DseGraph.g .withRemote(DseGraph.remoteConnectionBuilder(session).build()) .getGraph() .traversal(SocialTraversalSource.class);
All the DSE predicates are available on the driver side:
for search, use the Search class:
GraphTraversal<Vertex, String> traversal = g.V().has("recipe", "instructions", Search.token("Saute")).values("name");
for geospatial queries, use the Geo class:
GraphTraversal<Vertex, String> traversal = g.V() .has( "location", "point", Geo.inside(Geo.point(2.352222, 48.856614), 4.2, Geo.Unit.DEGREES)) .values("name");