Handling graph results

Script queries and explicit fluent traversals return graph result sets, which are essentially iterables of GraphNode.

Synchronous / asynchronous result

Like their CQL counterparts, graph result sets come in two forms, depending on the way the query was executed.

  • session.execute returns a GraphResultSet. It can be iterated directly, and will return the whole result set, triggering background fetches if the query is paged:

    for (GraphNode n : resultSet) {
      System.out.println(n);
    }
    
  • session.executeAsync returns an AsyncGraphResultSet. It only holds the current page of results, accessible via the currentPage() method. If the query is paged, the next pages must be fetched explicitly using the hasMorePages() and fetchNextPage() methods. See Asynchronous paging for more details about how to work with async types.

Note: at the time of writing (DSE 6.0), graph queries are never paged. Results are always returned as a single page. However, paging is on the roadmap for a future DSE version; the driver APIs reflect that, to avoid breaking changes when the feature is introduced.

Both types have a one() method, to use when you know there is exactly one node, or are only interested in the first one:

GraphNode n = resultSet.one();

Working with graph nodes

GraphNode wraps the responses returned by the server. Use the asXxx() methods to coerce a node to a specific type:

FluentGraphStatement statement = FluentGraphStatement.newInstance(g.V().count());
GraphNode n = session.execute(statement).one();
System.out.printf("The graph has %s vertices%n", n.asInt());

If the result is an array or “object” (in the JSON sense: a collection of named fields), you can iterate its children:

if (n.isList()) {
  for (int i = 0; i < n.size(); i++) {
    GraphNode child = n.getByIndex(i);
    System.out.printf("Element at position %d: %s%n", i, child);
  }

  // Alternatively, convert to a list:
  List<Object> l = n.asList();
}

if (n.isMap()) {
  for (Object key : n.keys()) {
    System.out.printf("Element at key %s: %s%n", key, n.getByKey(key));
  }

  // Alternatively, convert to a map:
  Map<String, Object> m = n.asMap();
}

Graph structural types

If the traversal returns graph elements (like vertices and edges), the results can be converted to the corresponding TinkerPop types:

GraphNode n = session.execute(FluentGraphStatement.newInstance(
    g.V().hasLabel("test_vertex")
)).one();
Vertex vertex = n.asVertex();

n = session.execute(FluentGraphStatement.newInstance(
    g.V().hasLabel("test_vertex").outE()
)).one();
Edge edge = n.asEdge();

n = session.execute(FluentGraphStatement.newInstance(
    g.V().hasLabel("test_vertex")
        .outE()
        .inV()
        .path()
)).one();
Path path = n.asPath();

n = session.execute(FluentGraphStatement.newInstance(
    g.V().hasLabel("test_vertex")
        .properties("name")
)).one();
// .properties() returns a list of properties, so we get the first one and transform it as a
// VertexProperty
VertexProperty vertexProperty = n.getByIndex(0).asVertexProperty();

Data type compatibility matrix

Dse graph exposes several data types when defining a schema for a graph. They translate into specific Java classes when the data is returned from the server.

Here is an exhaustive compatibility matrix (for DSE 6.0):

DSE graph Java driver
bigint Long
blob byte[]
boolean Boolean
date java.time.LocalDate
decimal BigDecimal
double Double
duration java.time.Duration
float Float
inet InetAddress
int Integer
linestring LineString
point Point
polygon Polygon
smallint Short
text String
time java.time.LocalTime
timestamp java.time.Instant
uuid UUID
varint BigInteger

If a type doesn’t have a corresponding asXxx() method, use the variant that takes a type token:

UUID uuid = graphNode.as(UUID.class);