Skip to content

GO

GO traverses in a graph with specified filters and returns 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 for N is one. When N is zero, NebulaGraph does not traverse any edges and returns nothing.

    Note

    The path type of the GO statement is walk, which means both vertices and edges can be repeatedly visited in graph traversal. For more information, see Path.

  • M TO N {STEP|STEPS}: traverses from M to N hops. When M is zero, the output is the same as that of M is one. That is, the output of GO 0 TO 2 and GO 1 TO 2 are the same.
  • <vertex_list>: represents a list of vertex IDs separated by commas, or a special place holder $-.id. For more information, see Pipe.
  • <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, the GO statement searches for outgoing edges of <vertex_list>. If REVERSELY is set, GO searches for incoming edges. If BIDIRECT is set, GO searches for edges of both directions.
  • WHERE <expression>: specifies the traversal filters. You can use the WHERE clause for the source vertices, the edges, and the destination vertices. You can use it together with AND, OR, NOT, and XOR. 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.
  • 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 use YIELD 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.

Examples

# The following example returns the teams that player 102 serves.
nebula> GO FROM "player102" OVER serve YIELD dst(edge);
+-----------+
| dst(EDGE) |
+-----------+
| "team203" |
| "team204" |
+-----------+
# The following example returns the friends of player 102 with 2 hops.
nebula> GO 2 STEPS FROM "player102" OVER follow YIELD dst(edge);
+-------------+
| dst(EDGE)   |
+-------------+
| "player101" |
| "player125" |
| "player100" |
| "player102" |
| "player125" |
+-------------+
# The following example adds a filter for the traversal.
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" |
+-----------------+------------+---------------------+
# The following example traverses along with multiple edge types. If there is no value for a property, the output is `NULL`.
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                        |
+-------------------------+-----------------------------+
# The following example returns the neighbor vertices in the incoming direction of player 100.
nebula> GO FROM "player100" OVER follow REVERSELY \
        YIELD src(edge) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player102" |
...

# This MATCH query shares the same semantics with the preceding GO query.
nebula> MATCH (v)<-[e:follow]- (v2) WHERE id(v) == 'player100' \
        RETURN id(v2) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player102" |
+-------------+
...
# The following example retrieves the friends of player 100 and the teams that they serve.
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"          |
...

# This MATCH query shares the same semantics with the preceding 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"          |
...
# The following example retrieves the friends of player 100 within 1 or 2 hops.
nebula> GO 1 TO 2 STEPS FROM "player100" OVER follow \
        YIELD dst(edge) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player125" |
...

# This MATCH query shares the same semantics with the preceding GO query.
nebula> MATCH (v) -[e:follow*1..2]->(v2) \
        WHERE id(v) == "player100" \
        RETURN id(v2) AS destination;
+-------------+
| destination |
+-------------+
| "player100" |
| "player102" |
...
# The following example 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]     |
+-------------+----------------------------+----------+
# 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      | follow._src | follow._dst |
+-------------+-------------+-------------+-------------+
| "player100" | "player125" | "player100" | "player101" |
| "player100" | "player101" | "player100" | "player125" |
+-------------+-------------+-------------+-------------+
# 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);
+-------------+
| follow._dst |
+-------------+
| "player125" |
| "player101" |
+-------------+

Last update: February 19, 2024