| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| |
| ## Handling graph results |
| |
| [Script queries](../script/) and [explicit fluent traversals](../fluent/explicit/) 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: |
| |
| ```java |
| 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](../../../paging/#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: |
| |
| ```java |
| 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: |
| |
| ```java |
| 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: |
| |
| ```java |
| 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: |
| |
| ```java |
| 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][DSE 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: |
| |
| ```java |
| UUID uuid = graphNode.as(UUID.class); |
| ``` |
| |
| [GraphNode]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/graph/GraphNode.html |
| [GraphResultSet]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/graph/GraphResultSet.html |
| [AsyncGraphResultSet]: https://docs.datastax.com/en/drivers/java/4.17/com/datastax/dse/driver/api/core/graph/AsyncGraphResultSet.html |
| |
| [DSE data types]: https://docs.datastax.com/en/dse/6.0/dse-dev/datastax_enterprise/graph/reference/refDSEGraphDataTypes.html |