GO¶
The GO
statement is used in the NebulaGraph database to traverse the graph starting from a given starting vertex with specified filters and return results.
OpenCypher compatibility¶
This topic applies to native nGQL only.
Syntax¶
GO [[<M> TO] <N> {STEP|STEPS}] FROM <vertex_list>
OVER <edge_type_list> [{REVERSELY | BIDIRECT}]
[ WHERE <conditions> ]
YIELD [DISTINCT] <return_list>
[{SAMPLE <sample_list> | <limit_by_list_clause>}]
[| GROUP BY {col_name | expr | position} YIELD <col_name>]
[| ORDER BY <expression> [{ASC | DESC}]]
[| LIMIT [<offset>,] <number_rows>];
<vertex_list> ::=
<vid> [, <vid> ...]
<edge_type_list> ::=
edge_type [, edge_type ...]
| *
<return_list> ::=
<col_name> [AS <col_alias>] [, <col_name> [AS <col_alias>] ...]
-
<N> {STEP|STEPS}
: specifies the hop number. If not specified, the default value forN
isone
. WhenN
iszero
, NebulaGraph does not traverse any edges and returns nothing.Note
The path type of the
GO
statement iswalk
, which means both vertices and edges can be repeatedly visited in graph traversal. For more information, see Path.
M TO N {STEP|STEPS}
: traversesfrom M to N
hops. WhenM
iszero
, the output is the same as that ofM
isone
. That is, the output ofGO 0 TO 2
andGO 1 TO 2
are the same.
<vertex_list>
: represents a list of vertex IDs separated by commas.
<edge_type_list>
: represents a list of edge types which the traversal can go through.
REVERSELY | BIDIRECT
: defines the direction of the query. By default, theGO
statement searches for outgoing edges of<vertex_list>
. IfREVERSELY
is set,GO
searches for incoming edges. IfBIDIRECT
is set,GO
searches for edges of both directions. The direction of the query can be checked by returning the<edge_type>._type
field usingYIELD
. A positive value indicates an outgoing edge, while a negative value indicates an incoming edge.
-
WHERE <expression>
: specifies the traversal filters. You can use theWHERE
clause for the source vertices, the edges, and the destination vertices. You can use it together withAND
,OR
,NOT
, andXOR
. For more information, see WHERE.Note
- There are some restrictions for the
WHERE
clause when you traverse along with multiple edge types. For example,WHERE edge1.prop1 > edge2.prop2
is not supported. - The GO statement is executed by traversing all the vertices and then filtering according to the filter condition.
- There are some restrictions for the
YIELD [DISTINCT] <return_list>
: defines the output to be returned. It is recommended to use the Schema-related functions to fill in<return_list>
.src(edge)
,dst(edge)
,type(edge) )
,rank(edge)
, etc., are currently supported, while nested functions are not. For more information, see YIELD.
SAMPLE <sample_list>
: takes samples from the result set. For more information, see SAMPLE.
<limit_by_list_clause>
: limits the number of outputs during the traversal process. For more information, see LIMIT.
GROUP BY
: groups the output into subgroups based on the value of the specified property. For more information, see GROUP BY. After grouping, you need to useYIELD
again to define the output that needs to be returned.
-
ORDER BY
: sorts outputs with specified orders. For more information, see ORDER BY.Note
When the sorting method is not specified, the output orders can be different for the same query.
LIMIT [<offset>,] <number_rows>]
: limits the number of rows of the output. For more information, see LIMIT.
Notes¶
- The
WHERE
andYIELD
clauses inGO
statements usually utilize property reference symbols ($^
and$$
) or theproperties($^)
andproperties($$)
functions to specify the properties of a vertex; use theproperties(edge)
function to specify the properties of an edge. For details, see Property Reference Symbols and Schema-related Functions.
- When referring to the result of a subquery in a compound
GO
statement, you need to set a name for the result and pass it to the next subquery using the pipe symbol|
, and reference the name of the result in the next subquery using$-
. See the Pipe Operator for details.
- When the queried property has no value, the returned result displays
NULL
.
Cases and examples¶
To query the immediate neighbors of a vertex¶
For example, to query the team that a person belongs to, assuming that the person is connected to the team by the serve
edge and the person's ID is player102
.
nebula> GO FROM "player102" OVER serve YIELD dst(edge);
+-----------+
| dst(EDGE) |
+-----------+
| "team203" |
| "team204" |
+-----------+
To query all vertices within a specified number of hops from a starting vertex¶
For example, to query all vertices within two hops of a person vertex, assuming that the person is connected to other people by the follow
edge and the person's ID is player102
.
# Return all vertices that are 2 hops away from the player102 vertex.
nebula> GO 2 STEPS FROM "player102" OVER follow YIELD dst(edge);
+-------------+
| dst(EDGE) |
+-------------+
| "player101" |
| "player125" |
| "player100" |
| "player102" |
| "player125" |
+-------------+
# Return all vertices within 1 or 2 hops away from the player102 vertex.
nebula> GO 1 TO 2 STEPS FROM "player100" OVER follow \
YIELD dst(edge) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player125" |
...
# The following MATCH query has the same semantics as the previous GO query.
nebula> MATCH (v) -[e:follow*1..2]->(v2) \
WHERE id(v) == "player100" \
RETURN id(v2) AS destination;
+-------------+
| destination |
+-------------+
| "player100" |
| "player102" |
...
To add filtering conditions¶
Case: To query the vertices and edges that meet specific conditions.
For example, use the WHERE
clause to query the edges with specific properties between the starting vertex and the destination vertex.
nebula> GO FROM "player100", "player102" OVER serve \
WHERE properties(edge).start_year > 1995 \
YIELD DISTINCT properties($$).name AS team_name, properties(edge).start_year AS start_year, properties($^).name AS player_name;
+-----------------+------------+---------------------+
| team_name | start_year | player_name |
+-----------------+------------+---------------------+
| "Spurs" | 1997 | "Tim Duncan" |
| "Trail Blazers" | 2006 | "LaMarcus Aldridge" |
| "Spurs" | 2015 | "LaMarcus Aldridge" |
+-----------------+------------+---------------------+
To query multiple edge types¶
Case: To query multiple edge types that are connected to the starting vertex. You can specify multiple edge types or the *
symbol to query multiple edge types.
For example, to query the follow
and serve
edges that are connected to the starting vertex.
nebula> GO FROM "player100" OVER follow, serve \
YIELD properties(edge).degree, properties(edge).start_year;
+-------------------------+-----------------------------+
| properties(EDGE).degree | properties(EDGE).start_year |
+-------------------------+-----------------------------+
| 95 | __NULL__ |
| 95 | __NULL__ |
| __NULL__ | 1997 |
+-------------------------+-----------------------------+
To query incoming vertices using the REVERSELY keyword¶
# Return the vertices that follow the player100 vertex.
nebula> GO FROM "player100" OVER follow REVERSELY \
YIELD src(edge) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player102" |
...
# The following MATCH query has the same semantics as the previous GO query.
nebula> MATCH (v)<-[e:follow]- (v2) WHERE id(v) == 'player100' \
RETURN id(v2) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player102" |
...
To use subqueries as the starting vertice of a graph traversal¶
# Return the friends of the player100 vertex and the teams that the friends belong to.
nebula> GO FROM "player100" OVER follow REVERSELY \
YIELD src(edge) AS id | \
GO FROM $-.id OVER serve \
WHERE properties($^).age > 20 \
YIELD properties($^).name AS FriendOf, properties($$).name AS Team;
+---------------------+-----------------+
| FriendOf | Team |
+---------------------+-----------------+
| "Boris Diaw" | "Spurs" |
| "Boris Diaw" | "Jazz" |
| "Boris Diaw" | "Suns" |
...
# The following MATCH query has the same semantics as the previous GO query.
nebula> MATCH (v)<-[e:follow]- (v2)-[e2:serve]->(v3) \
WHERE id(v) == 'player100' \
RETURN v2.player.name AS FriendOf, v3.team.name AS Team;
+---------------------+-----------------+
| FriendOf | Team |
+---------------------+-----------------+
| "Boris Diaw" | "Spurs" |
| "Boris Diaw" | "Jazz" |
| "Boris Diaw" | "Suns" |
...
To use GROUP BY
to group the output¶
You need to use YIELD
to define the output that needs to be returned after grouping.
# The following example collects the outputs according to age.
nebula> GO 2 STEPS FROM "player100" OVER follow \
YIELD src(edge) AS src, dst(edge) AS dst, properties($$).age AS age \
| GROUP BY $-.dst \
YIELD $-.dst AS dst, collect_set($-.src) AS src, collect($-.age) AS age;
+-------------+----------------------------+----------+
| dst | src | age |
+-------------+----------------------------+----------+
| "player125" | {"player101"} | [41] |
| "player100" | {"player125", "player101"} | [42, 42] |
| "player102" | {"player101"} | [33] |
+-------------+----------------------------+----------+
To use ORDER BY
and LIMIT
to sort and limit the output¶
# The following example groups the outputs and restricts the number of rows of the outputs.
nebula> $a = GO FROM "player100" OVER follow YIELD src(edge) AS src, dst(edge) AS dst; \
GO 2 STEPS FROM $a.dst OVER follow \
YIELD $a.src AS src, $a.dst, src(edge), dst(edge) \
| ORDER BY $-.src | OFFSET 1 LIMIT 2;
+-------------+-------------+-------------+-------------+
| src | $a.dst | src(EDGE) | dst(EDGE) |
+-------------+-------------+-------------+-------------+
| "player100" | "player101" | "player100" | "player101" |
| "player100" | "player125" | "player100" | "player125" |
+-------------+-------------+-------------+-------------+
Other examples¶
# The following example determines if $$.player.name IS NOT EMPTY.
nebula> GO FROM "player100" OVER follow WHERE properties($$).name IS NOT EMPTY YIELD dst(edge);
+-------------+
| dst(EDGE) |
+-------------+
| "player125" |
| "player101" |
+-------------+