Control Flow Statements
The GSQL Query Language includes a comprehensive set of control flow statements to empower sophisticated graph traversal and data computation: IF/ELSE, CASE, WHILE, and FOREACH.

Differences in Block Syntax

Note that any of these statements can be used as a query-body statement or as a DML-sub level statement.
If the control flow statement is at the query-body level, then its block(s) of statements are query-body statements ( queryBodyStmts ). In a queryBodyStmts block , each individual statement ends with a semicolon, so there is always a semicolon at the end.
If the control flow statement is at the DML-sub level, then its block(s) of statements are DML-sub statements ( dmlSubStmtList ). In a dmlSubStmtList block, a comma separates statements, but there is no punctuation at the end.
The "Statement Types" subsection in the Chapter on "CREATE / INSTALL / RUN / SHOW / DROP QUERY" has a more detailed general example of the difference between queryBodyStmts and dmlSubStmts.

IF Statement

The IF statement provides conditional branching: execute a block of statements ( queryBodyStmts or dmlSubStmtList ) only if a given condition is true. The IF statement allows for zero or more ELSE-IF clauses, followed by an optional ELSE clause. The IF statement can be used either at the query-body level or at the DML-sub-statement level. (See the note about differences in block syntax .)
IF syntax
1
queryBodyIfStmt := IF condition THEN queryBodyStmts
2
[ELSE IF condition THEN queryBodyStmts ]*
3
[ELSE queryBodyStmts ] END
4
dmlSubIfStmt := IF condition THEN dmlSubStmtList
5
[ELSE IF condition THEN dmlSubStmtList ]*
6
[ELSE dmlSubStmtList ] END
Copied!
If a particular IF condition is not true, then the flow proceeds to the next ELSE IF condition. When a true condition is encountered, its corresponding block of statements is executed, and then the IF statement terminates (skipping any remaining ELSE-IF or ELSE clauses). If an ELSE-clause is present, its block of statements are executed if none of the preceding conditions are true. Overall, the functionality can be summarized as "execute the first block of statements whose conditional test is true."
IF semantics
1
# if then
2
IF x == 5 THEN y = 10; END; # y is assigned to 10 only if x is 5.
3
4
# if then else
5
IF x == 5 THEN y = 10; # y is 10 only if x is 5.
6
ELSE y = 20; END; # y is 20 only if x is NOT 5.
7
8
#if with ELSE IF
9
IF x == 5 THEN y = 10; # y is 10 only if x is 5.
10
ELSE IF x == 7 THEN y = 5; # y is 5 only if x is 7.
11
ELSE y = 20; END; # y is 20 only if x is NOT 5 and NOT 7.
Copied!
Example 1. countFriendsOf2.gsql : Simple IF-ELSE at query-body level
1
# count the number of friends a person has, and optionally include coworkers in that count
2
CREATE QUERY countFriendsOf2(vertex<person> seed, BOOL includeCoworkers) FOR GRAPH friendNet
3
{
4
SumAccum<INT> @@numFriends = 0;
5
start = {seed};
6
7
IF includeCoworkers THEN
8
friends = SELECT v FROM start -((friend | coworker):e)-> :v
9
ACCUM @@numFriends +=1;
10
ELSE
11
friends = SELECT v FROM start -(friend:e)-> :v
12
ACCUM @@numFriends +=1;
13
END;
14
PRINT @@numFriends, includeCoworkers;
15
}
Copied!
Example 1 Results
1
GSQL > RUN QUERY countFriendsOf2("person2", true)
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{
11
"@@numFriends": 5,
12
"includeCoworkers": true
13
}]
14
}
15
GSQL > RUN QUERY countFriendsOf2("person2", false)
16
{
17
"error": false,
18
"message": "",
19
"version": {
20
"edition": "developer",
21
"schema": 0,
22
"api": "v2"
23
},
24
"results": [{
25
"@@numFriends": 2,
26
"includeCoworkers": false
27
}]
28
}
Copied!
Example 2. IF-ELSE IF-ELSE at query-body level
1
# determine if a user is active in terms of social networking (i.e., posts frequently)
2
CREATE QUERY calculateActivity(vertex<person> seed) FOR GRAPH socialNet
3
{
4
SumAccum<INT> @@numberPosts = 0;
5
start = {seed};
6
result = SELECT postVertex FROM start -(posted:e)-> :postVertex
7
ACCUM @@numberPosts += 1;
8
9
IF @@numberPosts < 2 THEN
10
PRINT "Not very active";
11
ELSE IF @@numberPosts < 3 THEN
12
PRINT "Semi-active";
13
ELSE
14
PRINT "Very active";
15
END;
16
}
Copied!
Example 2 Results for Query calculateActivity
1
GSQL > RUN QUERY calculateActivity("person1")
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"Not very active": "Not very active"}]
11
}
12
GSQL > RUN QUERY calculateActivity("person5")
13
{
14
"error": false,
15
"message": "",
16
"version": {
17
"edition": "developer",
18
"schema": 0,
19
"api": "v2"
20
},
21
"results": [{"Semi-active": "Semi-active"}]
22
}
Copied!
Example 3. Nested IF at query-body level
1
# use a more advanced activity calculation, taking into account number of posts
2
# and number of likes that a user made
3
CREATE QUERY calculateInDepthActivity(vertex<person> seed) FOR GRAPH socialNet
4
{
5
SumAccum<INT> @@numberPosts = 0;
6
SumAccum<INT> @@numberLikes = 0;
7
start = {seed};
8
result = SELECT postVertex FROM start -(posted:e)-> :postVertex
9
ACCUM @@numberPosts += 1;
10
result = SELECT likedPost FROM start -(liked:e)-> :likedPost
11
ACCUM @@numberLikes += 1;
12
13
IF @@numberPosts < 2 THEN
14
IF @@numberLikes < 1 THEN
15
PRINT "Not very active";
16
ELSE
17
PRINT "Semi-active";
18
END;
19
ELSE IF @@numberPosts < 3 THEN
20
IF @@numberLikes < 2 THEN
21
PRINT "Semi-active";
22
ELSE
23
PRINT "Active";
24
END;
25
ELSE
26
PRINT "Very active";
27
END;
28
}
Copied!
Example 3 Results for Query calculateInDepthActivity
1
GSQL > RUN QUERY calculateInDepthActivity("person1")
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"Semi-active": "Semi-active"}]
11
}
Copied!
Example 4. Nested IF at DML-sub level
1
# give each user post an accumulated rating based on the subject and how many likes it has
2
# This query is equivalent to the query ratePosts shown above
3
CREATE QUERY ratePosts2() FOR GRAPH socialNet {
4
SumAccum<INT> @rating = 0;
5
allPeople = {person.*};
6
7
results = SELECT v FROM allPeople -(:e)-> post:v
8
ACCUM IF e.type == "posted" THEN
9
IF v.subject == "cats" THEN
10
v.@rating += -1 # -1 if post is about cats
11
ELSE IF v.subject == "Graphs" THEN
12
v.@rating += 2 # +2 if post is about graphs
13
ELSE IF v.subject == "tigergraph" THEN
14
v.@rating += 10 # +10 if post is about tigergraph
15
END
16
ELSE IF e.type == "liked" THEN
17
v.@rating += 3 # +3 each time post was liked
18
END
19
ORDER BY v.@rating DESC
20
LIMIT 5;
21
PRINT results;
22
}
Copied!
Example 4 Results for Query ratePosts2
1
GSQL > RUN QUERY ratePosts2()
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"results": [
11
{
12
"v_id": "6",
13
"attributes": {
14
"postTime": "2011-02-05 02:02:05",
15
"subject": "tigergraph",
16
"@rating": 13
17
},
18
"v_type": "post"
19
},
20
{
21
"v_id": "0",
22
"attributes": {
23
"postTime": "2010-01-12 11:22:05",
24
"subject": "Graphs",
25
"@rating": 11
26
},
27
"v_type": "post"
28
},
29
{
30
"v_id": "1",
31
"attributes": {
32
"postTime": "2011-03-03 23:02:00",
33
"subject": "tigergraph",
34
"@rating": 10
35
},
36
"v_type": "post"
37
},
38
{
39
"v_id": "5",
40
"attributes": {
41
"postTime": "2011-02-06 01:02:02",
42
"subject": "tigergraph",
43
"@rating": 10
44
},
45
"v_type": "post"
46
},
47
{
48
"v_id": "4",
49
"attributes": {
50
"postTime": "2011-02-07 05:02:51",
51
"subject": "coffee",
52
"@rating": 6
53
},
54
"v_type": "post"
55
}
56
]}]
57
}
Copied!

CASE Statement

The CASE statement provides conditional branching: execute a block of statements only if a given condition is true. CASE statements can be used as query-body statements or DML-sub-statements. (See the note about differences in block syntax .)
CASE syntax
1
queryBodyCaseStmt := CASE (WHEN condition THEN queryBodyStmts)+ [ELSE queryBodyStmts] END
2
| CASE expr (WHEN constant THEN queryBodyStmts)+ [ELSE queryBodyStmts] END
3
dmlSubCaseStmt := CASE (WHEN condition THEN dmlSubStmtList)+ [ELSE dmlSubStmtList] END
4
| CASE expr (WHEN constant THEN dmlSubStmtList)+ [ELSE dmlSubStmtList] END
Copied!
One CASE statement contains one or more WHEN-THEN clauses, each WHEN presenting one expression. The CASE statement may also have one ELSE clause whose statements are executed if none of the preceding conditions are true.
There are two syntaxes of the CASE statement: one equivalent to an if-else statement, and the other is structured like a switch statement. The if-else version evaluates the boolean condition within each WHEN-clause and executes the first block of statements whose condition is true. The optional concluding ELSE-clause is executed only if all WHEN-clause conditions are false.
The switch version evaluates the expression following the keyword WHEN and compares its value to the expression immediately following the keyword CASE. These expressions do not need to be boolean; the CASE statement compares pairs of expressions to see if their values are equal. The first WHEN-THEN clause to have an expression value equal to the CASE expression value is executed; the remaining clauses are skipped. The optional ELSE-clause is executed only if no WHEN-clause expression has a value matching the CASE value.
CASE Semantics
1
STRING drink = "Juice";
2
3
# CASE statement: if-else version
4
CASE
5
WHEN drink == "Juice" THEN @@calories += 50
6
WHEN drink == "Soda" THEN @@calories += 120
7
...
8
ELSE @@calories = 0 # Optional else-clause
9
END
10
# Since drink = "Juice", 50 will be added to calories
11
12
# CASE statement: switch version
13
CASE drink
14
WHEN "Juice" THEN @@calories += 50
15
WHEN "Soda" THEN @@calories += 120
16
...
17
ELSE @@calories = 0 # Optional else-clause
18
END
19
# Since drink = "Juice", 50 will be added to calories
Copied!
Example 1. CASE as IF-ELSE
1
# Display the total number times connected users posted about a certain subject
2
CREATE QUERY userNetworkPosts (vertex<person> seedUser, STRING subjectName) FOR GRAPH socialNet {
3
SumAccum<INT> @@topicSum = 0;
4
OrAccum @visited;
5
reachableVertices = {}; # empty vertex set
6
visitedVertices (ANY) = {seedUser}; # set that can contain ANY type of vertex
7
8
WHILE visitedVertices.size() !=0 DO # loop terminates when all neighbors are visited
9
visitedVertices = SELECT s # s is all neighbors of visitedVertices which have not been visited
10
FROM visitedVertices-(:e)->:s
11
WHERE s.@visited == false
12
ACCUM s.@visited = true,
13
CASE
14
WHEN s.type == "post" and s.subject == subjectName THEN @@topicSum += 1
15
END;
16
END;
17
PRINT @@topicSum;
18
}
Copied!
Example 1 Results for Query userNetworkPosts
1
GSQL > RUN QUERY userNetworkPosts("person1", "Graphs")
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"@@topicSum": 3}]
11
}
Copied!
Example 2. CASE as switch
1
# tally male and female friends of the starting vertex
2
CREATE QUERY countGenderOfFriends(vertex<person> seed) FOR GRAPH socialNet {
3
SumAccum<INT> @@males = 0;
4
SumAccum<INT> @@females = 0;
5
SumAccum<INT> @@unknown = 0;
6
startingVertex = {seed};
7
8
people = SELECT v FROM startingVertex -(friend:e)->:v
9
ACCUM CASE v.gender
10
WHEN "Male" THEN @@males += 1
11
WHEN "Female" THEN @@females +=1
12
ELSE @@unknown += 1
13
END;
14
PRINT @@males, @@females, @@unknown;
15
}
Copied!
Example 2 Results for Query countGenderOfFriends
1
GSQL > RUN QUERY countGenderOfFriends("person4")
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{
11
"@@males": 2,
12
"@@unknown": 0,
13
"@@females": 1
14
}]
15
}
Copied!
Example 3. Multiple CASE statements
1
# give each social network user a social impact score which accumulates
2
# based on how many friends and posts they have
3
CREATE QUERY scoreSocialImpact() FOR GRAPH socialNet api("v2") {
4
SumAccum<INT> @socialImpact = 0;
5
allPeople = {person.*};
6
people = SELECT v FROM allPeople:v
7
ACCUM CASE WHEN v.outdegree("friend") > 1 THEN v.@socialImpact +=1 END, # +1 point for having > 1 friend
8
CASE WHEN v.outdegree("friend") > 2 THEN v.@socialImpact +=1 END, # +1 point for having > 2 friends
9
CASE WHEN v.outdegree("posted") > 1 THEN v.@socialImpact +=1 END, # +1 point for having > 1 posts
10
CASE WHEN v.outdegree("posted") > 3 THEN v.@socialImpact +=2 END; # +2 points for having > 2 posts
11
#PRINT people.@socialImpact; // api v1
12
PRINT people[people.@socialImpact]; // api v2
13
}
Copied!
Example 3 Results for Query scoreSocialImpact
1
GSQL > RUN QUERY scoreSocialImpact()
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"people": [
11
{
12
"v_id": "person4",
13
"attributes": {"[email protected]": 2},
14
"v_type": "person"
15
},
16
{
17
"v_id": "person3",
18
"attributes": {"[email protected]": 1},
19
"v_type": "person"
20
},
21
{
22
"v_id": "person7",
23
"attributes": {"[email protected]": 2},
24
"v_type": "person"
25
},
26
{
27
"v_id": "person1",
28
"attributes": {"[email protected]": 1},
29
"v_type": "person"
30
},
31
{
32
"v_id": "person5",
33
"attributes": {"[email protected]": 2},
34
"v_type": "person"
35
},
36
{
37
"v_id": "person6",
38
"attributes": {"[email protected]": 2},
39
"v_type": "person"
40
},
41
{
42
"v_id": "person2",
43
"attributes": {"[email protected]": 1},
44
"v_type": "person"
45
},
46
{
47
"v_id": "person8",
48
"attributes": {"[email protected]": 3},
49
"v_type": "person"
50
}
51
]}]
52
}
Copied!
Example 4. Nested CASE statements
1
# give each user post a rating based on the subject and how many likes it has
2
CREATE QUERY ratePosts() FOR GRAPH socialNet api("v2") {
3
SumAccum<INT> @rating = 0;
4
allPeople = {person.*};
5
6
results = SELECT v FROM allPeople -(:e)-> post:v
7
ACCUM CASE e.type
8
WHEN "posted" THEN
9
CASE
10
WHEN v.subject == "cats" THEN v.@rating += -1 # -1 if post about cats
11
WHEN v.subject == "Graphs" THEN v.@rating += 2 # +2 if post about graphs
12
WHEN v.subject == "tigergraph" THEN v.@rating += 10 # +10 if post about tigergraph
13
END
14
WHEN "liked" THEN v.@rating += 3 # +3 each time post was liked
15
END;
16
#PRINT results.@rating; // api v1
17
PRINT results[results.@rating]; // api v2
18
}
Copied!
Example 4 Results for Query ratePosts
1
GSQL > RUN QUERY ratePosts()
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"results": [
11
{
12
"v_id": "0",
13
"attributes": {"[email protected]": 11},
14
"v_type": "post"
15
},
16
{
17
"v_id": "10",
18
"attributes": {"[email protected]": 2},
19
"v_type": "post"
20
},
21
{
22
"v_id": "2",
23
"attributes": {"[email protected]": 0},
24
"v_type": "post"
25
},
26
{
27
"v_id": "4",
28
"attributes": {"[email protected]": 6},
29
"v_type": "post"
30
},
31
{
32
"v_id": "9",
33
"attributes": {"[email protected]": -1},
34
"v_type": "post"
35
},
36
{
37
"v_id": "3",
38
"attributes": {"[email protected]": 2},
39
"v_type": "post"
40
},
41
{
42
"v_id": "5",
43
"attributes": {"[email protected]": 10},
44
"v_type": "post"
45
},
46
{
47
"v_id": "7",
48
"attributes": {"[email protected]": 2},
49
"v_type": "post"
50
},
51
{
52
"v_id": "1",
53
"attributes": {"[email protected]": 10},
54
"v_type": "post"
55
},
56
{
57
"v_id": "11",
58
"attributes": {"[email protected]": -1},
59
"v_type": "post"
60
},
61
{
62
"v_id": "8",
63
"attributes": {"[email protected]": 2},
64
"v_type": "post"
65
},
66
{
67
"v_id": "6",
68
"attributes": {"[email protected]": 13},
69
"v_type": "post"
70
}
71
]}]
72
}
Copied!

WHILE Statement

The WHILE statement provides unbounded iteration over a block of statements. WHILE statements can be used as query-body statements or DML-sub-statements. (See the note about differences in block syntax .)
WHILE syntax
1
queryBodyWhileStmt := WHILE condition [LIMIT simpleSize] DO queryBodyStmts END
2
dmlSubWhileStmt := WHILE condition [LIMIT simpleSize] DO dmlSubStmtList END
3
simpleSize := integer | varName | paramName
Copied!
The WHILE statement iterates over its body ( queryBodyStmts or dmlSubStmtList ) until the condition evaluates to false or until the iteration limit is met. A condition is any expression that evaluates to a boolean. The condition is evaluated before each iteration. CONTINUE statements can be used to change the control flow within the while block. BREAK statements can be used to exit the while loop.
A WHILE statement may have an optional LIMIT clause. LIMIT clauses has a constant positive integer value or integer variable to constrain the maximum number of loop iterations. The example below demonstrates how the LIMIT behaves.
If a limit value is not specified, it is possible for a WHILE loop to iterate infinitely. It is the responsibility of the query author to design the condition logic so that it is guaranteed to eventually be true (or to set a limit).
WHILE LIMIT semantics
1
# These three WHILE statements behave the same. Each terminates when
2
# (v.size == 0) or after 5 iterations of the loop.
3
WHILE v.size() !=0 LIMIT 5 DO
4
# Some statements
5
END;
6
7
INT iter = 0;
8
WHILE (v.size() !=0) AND (iter < 5) DO
9
# Some statements
10
iter = iter + 1;
11
END;
12
13
INT iter = 0;
14
WHILE v.size() !=0 DO
15
IF iter == 5 THEN BREAK; END;
16
# Some statements
17
iter = iter + 1;
18
END;
Copied!
Below are a number of examples that demonstrate the use of WHILE statements.
Example 1. Simple WHILE loop
1
# find all vertices which are reachable from a starting seed vertex (i.e., breadth-first search)
2
CREATE QUERY reachable(vertex<person> seed) FOR GRAPH workNet
3
{
4
OrAccum @visited;
5
reachableVertices = {}; # empty vertex set
6
visitedVertices (ANY) = {seed}; # set that can contain ANY type of vertex
7
8
WHILE visitedVertices.size() !=0 DO # loop terminates when all neighbors are visited
9
visitedVertices = SELECT s # s is all neighbors of visitedVertices which have not been visited
10
FROM visitedVertices-(:e)->:s
11
WHERE s.@visited == false
12
POST-ACCUM s.@visited = true;
13
reachableVertices = reachableVertices UNION visitedVertices;
14
END;
15
PRINT reachableVertices;
16
}
Copied!
reachable Results
1
GSQL > RUN QUERY reachable("person1")
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"reachableVertices": [
11
{
12
"v_id": "person3",
13
"attributes": {
14
"interestList": ["teaching"],
15
"skillSet": [ 6, 1, 4 ],
16
"skillList": [ 4, 1, 6 ],
17
"locationId": "jp",
18
"interestSet": ["teaching"],
19
"@visited": true,
20
"id": "person3"
21
},
22
"v_type": "person"
23
},
24
{
25
"v_id": "person9",
26
"attributes": {
27
"interestList": [ "financial", "teaching" ],
28
"skillSet": [ 2, 7, 4 ],
29
"skillList": [ 4, 7, 2 ],
30
"locationId": "us",
31
"interestSet": [ "teaching", "financial" ],
32
"@visited": true,
33
"id": "person9"
34
},
35
"v_type": "person"
36
},
37
{
38
"v_id": "person4",
39
"attributes": {
40
"interestList": ["football"],
41
"skillSet": [ 10, 1, 4 ],
42
"skillList": [ 4, 1, 10 ],
43
"locationId": "us",
44
"interestSet": ["football"],
45
"@visited": true,
46
"id": "person4"
47
},
48
"v_type": "person"
49
},
50
{
51
"v_id": "person7",
52
"attributes": {
53
"interestList": [ "art", "sport" ],
54
"skillSet": [ 6, 8 ],
55
"skillList": [ 8, 6 ],
56
"locationId": "us",
57
"interestSet": [ "sport", "art" ],
58
"@visited": true,
59
"id": "person7"
60
},
61
"v_type": "person"
62
},
63
{
64
"v_id": "person1",
65
"attributes": {
66
"interestList": [ "management", "financial" ],
67
"skillSet": [ 3, 2, 1 ],
68
"skillList": [ 1, 2, 3 ],
69
"locationId": "us",
70
"interestSet": [ "financial", "management" ],
71
"@visited": true,
72
"id": "person1"
73
},
74
"v_type": "person"
75
},
76
{
77
"v_id": "person5",
78
"attributes": {
79
"interestList": [ "sport", "financial", "engineering" ],
80
"skillSet": [ 5, 2, 8 ],
81
"skillList": [ 8, 2, 5 ],
82
"locationId": "can",
83
"interestSet": [ "engineering", "financial", "sport" ],
84
"@visited": true,
85
"id": "person5"
86
},
87
"v_type": "person"
88
},
89
{
90
"v_id": "person6",
91
"attributes": {
92
"interestList": [ "music", "art" ],
93
"skillSet": [ 10, 7 ],
94
"skillList": [ 7, 10 ],
95
"locationId": "jp",
96
"interestSet": [ "art", "music" ],
97
"@visited": true,
98
"id": "person6"
99
},
100
"v_type": "person"
101
},
102
{
103
"v_id": "person2",
104
"attributes": {
105
"interestList": ["engineering"],
106
"skillSet": [ 6, 5, 3, 2 ],
107
"skillList": [ 2, 3, 5, 6 ],
108
"locationId": "chn",
109
"interestSet": ["engineering"],
110
"@visited": true,
111
"id": "person2"
112
},
113
"v_type": "person"
114
},
115
{
116
"v_id": "person8",
117
"attributes": {
118
"interestList": ["management"],
119
"skillSet": [ 2, 5, 1 ],
120
"skillList": [ 1, 5, 2 ],
121
"locationId": "chn",
122
"interestSet": ["management"],
123
"@visited": true,
124
"id": "person8"
125
},
126
"v_type": "person"
127
},
128
{
129
"v_id": "company3",
130
"attributes": {
131
"country": "jp",
132
"@visited": true,
133
"id": "company3"
134
},
135
"v_type": "company"
136
},
137
{
138
"v_id": "company2",
139
"attributes": {
140
"country": "chn",
141
"@visited": true,
142
"id": "company2"
143
},
144
"v_type": "company"
145
},
146
{
147
"v_id": "company1",
148
"attributes": {
149
"country": "us",
150
"@visited": true,
151
"id": "company1"
152
},
153
"v_type": "company"
154
},
155
{
156
"v_id": "person10",
157
"attributes": {
158
"interestList": [ "football", "sport" ],
159
"skillSet": [3],
160
"skillList": [3],
161
"locationId": "us",
162
"interestSet": [ "sport", "football" ],
163
"@visited": true,
164
"id": "person10"
165
},
166
"v_type": "person"
167
}
168
]}]
169
}
Copied!
Example 2. WHILE loop using a LIMIT
1
# find all vertices which are reachable within two hops from a starting seed vertex (i.e., breadth-first search)
2
CREATE QUERY reachableWithinTwo(vertex<person> seed) FOR GRAPH workNet
3
{
4
OrAccum @visited;
5
reachableVertices = {}; # empty vertex set
6
visitedVertices (ANY) = {seed}; # set that can contain ANY type of vertex
7
8
WHILE visitedVertices.size() !=0 LIMIT 2 DO # loop terminates when all neighbors within 2-hops of the seed vertex are visited
9
visitedVertices = SELECT s # s is all neighbors of visitedVertices which have not been visited
10
FROM visitedVertices-(:e)->:s
11
WHERE s.@visited == false
12
POST-ACCUM s.@visited = true;
13
reachableVertices = reachableVertices UNION visitedVertices;
14
END;
15
PRINT reachableVertices;
16
}
Copied!
reachableWithinTwo Results
1
GSQL > RUN QUERY reachableWithinTwo("person1")
2
{
3
"error": false,
4
"message": "",
5
"version": {
6
"edition": "developer",
7
"schema": 0,
8
"api": "v2"
9
},
10
"results": [{"reachableVertices": [
11
{
12
"v_id": "person4",
13
"attributes": {
14
"interestList": ["football"],
15
"skillSet": [ 10, 1, 4 ],
16
"skillList": [ 4, 1, 10 ],
17
"locationId": "us",
18
"interestSet": ["football"],
19
"@visited": true,
20
"id": "person4"
21
},
22
"v_type": "person"
23
},
24
{
25
"v_id": "person3",
26
"attributes": {
27
"interestList": ["teaching"],
28
"skillSet": [ 6, 1, 4 ],
29
"skillList": [ 4, 1, 6 ],
30
"locationId": "jp",
31
"interestSet": ["teaching"],
32
"@visited": true,