Skip to main content
Version: 3.10.0

GET SUBGRAPH

The GET SUBGRAPH statement returns a subgraph that is generated by traversing a graph starting from a specified vertex. GET SUBGRAPH statements allow you to specify the number of steps and the type or direction of edges during the traversal.

Syntax​

GET SUBGRAPH [WITH PROP] [<step_count> {STEP|STEPS}] FROM {<vid>, <vid>...}
[{IN | OUT | BOTH} <edge_type>, <edge_type>...]
[WHERE <expression> [AND <expression> ...]]
YIELD {[VERTICES AS <vertex_alias>] [,EDGES AS <edge_alias>]};
  • WITH PROP shows the properties. If not specified, the properties will be hidden.

  • step_count specifies the number of hops from the source vertices and returns the subgraph from 0 to step_count hops. It must be a non-negative integer. Its default value is 1.

  • vid specifies the vertex IDs.

  • edge_type specifies the edge type. You can use IN, OUT, and BOTH to specify the traversal direction of the edge type. The default is BOTH.

  • <WHERE clause> specifies the filter conditions for the traversal, which can be used with the boolean operator AND.

  • YIELD defines the output that needs to be returned. You can return only vertices or edges. A column alias must be set.

note

The path type of GET SUBGRAPH is trail. Only vertices can be repeatedly visited in graph traversal. For more information, see Path.

Limitations​

While using the WHERE clause in a GET SUBGRAPH statement, note the following restrictions:

  • Only support the AND operator.
  • Only support filter destination vertex, the vertex format must be $$.tagName.propName.
  • Support filter edge, the edge format must be edge_type.propName.
  • Support math functions, aggregate functions, string functions, datetime functions, type conversion functions and general functions in list functions.
  • Not support aggregate functions, schema-related functions, conditional expression, predicate functions, geography function and user-defined functions.

Examples​

The following graph is used as the sample.

A sample graph for GET SUBGRAPH

Insert the test data:

nebula> CREATE SPACE IF NOT EXISTS subgraph(partition_num=15, replica_factor=1, vid_type=fixed_string(30));
nebula> USE subgraph;
nebula> CREATE TAG IF NOT EXISTS player(name string, age int);
nebula> CREATE TAG IF NOT EXISTS team(name string);
nebula> CREATE EDGE IF NOT EXISTS follow(degree int);
nebula> CREATE EDGE IF NOT EXISTS serve(start_year int, end_year int);
nebula> INSERT VERTEX player(name, age) VALUES "player100":("Tim Duncan", 42);
nebula> INSERT VERTEX player(name, age) VALUES "player101":("Tony Parker", 36);
nebula> INSERT VERTEX player(name, age) VALUES "player102":("LaMarcus Aldridge", 33);
nebula> INSERT VERTEX team(name) VALUES "team203":("Trail Blazers"), "team204":("Spurs");
nebula> INSERT EDGE follow(degree) VALUES "player101" -> "player100":(95);
nebula> INSERT EDGE follow(degree) VALUES "player101" -> "player102":(90);
nebula> INSERT EDGE follow(degree) VALUES "player102" -> "player100":(75);
nebula> INSERT EDGE serve(start_year, end_year) VALUES "player101" -> "team204":(1999, 2018),"player102" -> "team203":(2006, 2015);
  • This example goes one step from the vertex player101 over all edge types and gets the subgraph.

    nebula> GET SUBGRAPH 1 STEPS FROM "player101" YIELD VERTICES AS nodes, EDGES AS relationships;
    +-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
    | nodes | relationships |
    +-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
    | [("player101" :player{})] | [[:serve "player101"->"team204" @0 {}], [:follow "player101"->"player100" @0 {}], [:follow "player101"->"player102" @0 {}]] |
    | [("team204" :team{}), ("player100" :player{}), ("player102" :player{})] | [[:follow "player102"->"player100" @0 {}]] |
    +-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+

    The returned subgraph is as follows.

    GET SUBGRAPH FROM "player101"

  • This example goes one step from the vertex player101 over incoming follow edges and gets the subgraph.

    nebula> GET SUBGRAPH 1 STEPS FROM "player101" IN follow YIELD VERTICES AS nodes, EDGES AS relationships;
    +---------------------------+---------------+
    | nodes | relationships |
    +---------------------------+---------------+
    | [("player101" :player{})] | [] |
    +---------------------------+---------------+

    There is no incoming follow edge to player101, so only the vertex player101 is returned.

  • This example goes one step from the vertex player101 over outgoing serve edges, gets the subgraph, and shows the property of the edge.

    nebula> GET SUBGRAPH WITH PROP 1 STEPS FROM "player101" OUT serve YIELD VERTICES AS nodes, EDGES AS relationships;
    +-------------------------------------------------------+-------------------------------------------------------------------------+
    | nodes | relationships |
    +-------------------------------------------------------+-------------------------------------------------------------------------+
    | [("player101" :player{age: 36, name: "Tony Parker"})] | [[:serve "player101"->"team204" @0 {end_year: 2018, start_year: 1999}]] |
    | [("team204" :team{name: "Spurs"})] | [] |
    +-------------------------------------------------------+-------------------------------------------------------------------------+

    The returned subgraph is as follows.

    GET SUBGRAPH FROM "101" OUT serve

  • This example goes two steps from the vertex player101 over follow edges, filters by degree > 90 and age > 30, and shows the properties of edges.

    nebula> GET SUBGRAPH WITH PROP 2 STEPS FROM "player101" \
    WHERE follow.degree > 90 AND $$.player.age > 30 \
    YIELD VERTICES AS nodes, EDGES AS relationships;
    +-------------------------------------------------------+------------------------------------------------------+
    | nodes | relationships |
    +-------------------------------------------------------+------------------------------------------------------+
    | [("player101" :player{age: 36, name: "Tony Parker"})] | [[:follow "player101"->"player100" @0 {degree: 95}]] |
    | [("player100" :player{age: 42, name: "Tim Duncan"})] | [] |
    +-------------------------------------------------------+------------------------------------------------------+

FAQ​

Why is the number of hops in the returned result greater than step_count?​

To show the completeness of the subgraph, an additional hop is made on all vertices that meet the conditions. The following graph is used as the sample.

FAQ

  • The returned paths of GET SUBGRAPH 1 STEPS FROM "A"; are A->B, B->A, and A->C. To show the completeness of the subgraph, an additional hop is made on all vertices that meet the conditions, namely B->C.

  • The returned path of GET SUBGRAPH 1 STEPS FROM "A" IN follow; is B->A. To show the completeness of the subgraph, an additional hop is made on all vertices that meet the conditions, namely A->B.

If you only query paths or vertices that meet the conditions, we suggest you use MATCH or GO. The example is as follows.

nebula> MATCH p= (v:player) -- (v2) WHERE id(v)=="A" RETURN p;
nebula> GO 1 STEPS FROM "A" OVER follow YIELD src(edge),dst(edge);

Why is the number of hops in the returned result lower than step_count?​

The query stops when there is not enough subgraph data and will not return the null value.

nebula> GET SUBGRAPH 100 STEPS FROM "player101" OUT follow YIELD VERTICES AS nodes, EDGES AS relationships;
+----------------------------------------------------+--------------------------------------------------------------------------------------+
| nodes | relationships |
+----------------------------------------------------+--------------------------------------------------------------------------------------+
| [("player101" :player{})] | [[:follow "player101"->"player100" @0 {}], [:follow "player101"->"player102" @0 {}]] |
| [("player100" :player{}), ("player102" :player{})] | [[:follow "player102"->"player100" @0 {}]] |
+----------------------------------------------------+--------------------------------------------------------------------------------------+