DSL Syntax
Syntax Introduction
The Algorithm query API is a graph DSL provided by GES. You can use it to query and calculate graphs. During service planning, various query operators and fine-grained basic computing pattern operators are added to DSL so that DSL can support user-defined graph traversal, multi-hop filtering query, pattern matching, similarity algorithms, community algorithms, recommendation algorithms, path analysis, and custom service algorithms.
For example, to query the neighborhood vertex set of the second hop from vertices 1 and 2, run the following command:
Match<Vertex> v(['1','2']); v.repeat(bothV()).times(2).limit(3); return v;
DSL Statement Construction
Statements are DSL program fragments that are executed in sequence. To enrich DSL's capability of expressing user-defined algorithms, DSL supports the following statements: selection statement, loop statement, expression statement, operator operand, declaration statement, and jump statement. Typically, the DSL structure consists of a declaration statement, an expression statement, and a jump statement. For example:
GlobalAcc<Sum,int> g=0; // Declaration statement, which declares an aggregator variable g g+=1*3+2; // Expression statement, which is used to perform the aggregation operation on the aggregator g. g = g + 1 x 3 + 2 return g; // Jump statement, which ends DSL and returns g
Currently, only the following selection and loop statements are supported, which are written in selection, loop, and lambda expressions:
- Assignment/aggregation of various expressions
- Update operator of the Vertex matcher
- Gather operator of the Vertex matcher
Syntax |
Keyword |
Description |
---|---|---|
Select statement |
if |
Executes a statement conditionally. |
Loop statement |
while |
Executes statements repeatedly. |
Jump statement |
return |
Returns different types of results. |
Declaration statement |
Match< ? > |
Declares a matcher Match to quickly match graph data for more operations. |
VertexAcc< ?, ?> |
Declares a vertex aggregator to define additional properties/variables on a vertex. Match can be used to perform operations on additional variables on vertices in batches. |
|
GlobalAcc< ?, ?> |
Declares a global aggregator to define globally operable variables. |
|
Expression statement |
operator= |
Assigns values to variables. |
operator+= |
Variable aggregation operation |
|
Arithmetic operations +, -, *, / |
Arithmetic operations |
|
Comparison operations >, >=, ==, <, <=, != |
Comparative operations |
|
lambda expression |
Anonymous expressions |
|
Operator operation statement |
repeat |
Allows users to perform multi-hop filtering query. The syntax includes emit, times, and limit. |
update |
Performs a set of batch operations defined on the matcher |
|
gather |
Performs a set of batch operations defined on the matcher |
|
pick |
Quickly obtains N random vertices |
|
init |
Reinitializes the vertex set of the vertex matcher |
|
insert |
Adds a matching vertex set to the vertex matcher |
|
move |
Quickly moves the vertex set in other_match_vertex to the match_vertex matcher |
|
subgraph |
It is mainly used in the return statement. It can return guidance subgraphs of the match_vertex vertex matcher. |
|
intersection |
Takes the intersection of two vertex matchers |
|
pattern |
Executes a complete Cypher statement and places the result in the vertex matcher |
- Select statement: if
if(expression) { true Branching statement }
Executes a statement conditionally.
GlobalAcc<Sum, int> threshold = 10; Match<Vertex> v(['1', '2']); if(threshold < 20) { v.repeat(outV().has('name', 'peter')).times(2).emit(); }
- Loop statement: while
while(expression) { true Branching statement }
Executes some code repeatedly and conditionally
GlobalAcc<Sum, int> loop = 0; VertexAcc<Sum, int> score = 1; Match<Vertex> v(['1', '2']); while(loop < 10) { loop +=1; v.update((v)->{v.score = 1 + 2 * v.score;}); }
- Jump statement: return
Returns JSON files of different types and formats
Type
Return Type
Description
Match
Vertex set
-
VertexAcc
map
By default, values that are not changed after initialization are not output.
GlobalAcc
Single value
-
subgraph
Vertex set and edge set
-
If some vertices are matched, they can be directly returned:
Match<Vertex> v(['1','2']); return v; { "vertices": [ { "id": "1", "label": "movie", "properties": { "genres": [ "Comedy" ] } } ... ] }
Alternatively, ACC values can be directly returned.
GlobalAcc<Max,int> g1=10; g1+=2; return g1; { "data": { "value": 10 } }
Assume that you want to obtain the guidance subgraph of a match vertex set for subsequent task execution (for example, drawing on the canvas).
Match<Vertex> v(['1','2']); return v.subgraph(); { "data": { "vertices": [ { "id": "1", "label": "user", "properties": { //balabala } }, { "id": "2", "label": "movie", "properties": { //balabala } } ], "edges": [ { "index": "0", "source": "1", "label": "rate", "properties": { //balabala }, "target": "2" } ] } }
- Expression statement
An expression is a sequence of operators and operands, which specifies a calculation. Different statements may use expressions. For example, loop statements and selection statements may use expressions to express branches or loop conditions. Expressions can also be used to assign values to variables and perform aggregation operations.
- The following table lists common operators:
Common Operator
Form
Symbol
Assignment
a=b;
=
Aggregation
a+=b
+=
Mathmetical
a+b;a-b;a*b;a/b
+, -, *, /
Comparison
a>b; a=b;a<=b;a==b;a!=b
>, >=, ==, <, <=, !=
The calculation of aggregation operations is determined by the definition of Aggregator.
- The following table lists the priorities among expressions:
Priority
Operator
Combination
1
() Function call [] Subscript .Member access a++ Suffix auto-increment a-- Suffix auto-decrement
Left to right
2
a*b a/b Multiplication and division
Left to right
3
a+b a-b Addition and subtraction
Left to right
4
< <= > >= Relational operators
Left to right
5
== != Equality operators
Left to right
6
and Logical AND
Left to right
7
or Logical OR
Left to right
8
= += Assignment, aggregation operations
Right to left
- Expression types
Due to the particularity of variables (different types of aggregators), DSL classifies expressions into the following types:
- numeric expression - Numerical expression
- vertexacc expression - Expression containing the vertexacc variable
- globalacc expression - Expression containing the globalacc variable
1+2*3 // Numerical expression GlobalAcc<Sum, int> diff = 0; VertexAcc<Sum, int> score = 0; Match<Vertex> v(['Tom']); 1+diff*2 // Expression with globalAcc, which belongs to globalacc expression 1+v.score*2 // Expression with vertexAcc, which belongs to vertexacc expression
- Expression upgrade table
There are different constraints on assignment and calculation for different types of expressions. That is, whether the assignment and calculation between different types are valid is restricted.
The following expressions are used to indicate whether assignment/aggregation operations support different expressions.
Left Value/Right Value
Numeric Expression
VertexAcc Expression
GlobalAcc Expression
vertexacc variable
vertexacc expression
Partially supported, the same matcher required
vertexacc expression
globalacc variable
globalacc expression
Not supported
globalacc expression
- Value promotion strategy
During the calculation of an expression, a right value can be converted into a value of another type. The following lists only the supported value promotion strategies:
- Integer value promotion: Boolean values can be converted to integer values. The value false changes to 0, and the value true changes to 1.
- Floating-point value promotion: Right values of the floating-point type can be converted to values of the double type without changing the values.
- Value conversion
Value conversion is currently not supported. Unlike promotion, value conversions can change values and have potential precision losses.
- Lambda expressions
($parameters)->{statements;}
It is mainly used to receive some steps of a function. For example, both the gather and update steps support transferring lambda expressions as parameters. Variables such as GlobalAcc and VertexAcc are used in lambda expressions to assign and aggregate values. Note the following:
- The parameter type does not need to be declared and can be identified in a unified manner.
- GlobalAcc in the context can be accessed by lambda expressions.
- Lambda expressions can be executed as independent function bodies. The input parameters must be empty.
GlobalAcc<Sum,int> g1=0; g1+=2*10+1; ()->{g1+=2*10+1;} // Same result as the previous statement // update receives lambda as a parameter: v.update((v1)->{g1+=v1.acc1*2+g2+v1.acc2;});
- The following table lists common operators:
Variable Declaration
- Match matcher description
DSL allows you to define objects such as vertices, paths, and submaps that can be matched and on which related operations can be performed. After declaring and initializing the matcher, you can use the matcher operator to perform operations on vertex sets in batches. For details, see Match matcher operators. Run the following statement to declare and initialize the matcher:
Match<[Vertex|Path|Subgraph]> $variable;
DSL allows you to define vertices, paths, and submaps that can be matched and on which related operations can be performed.
Match<Vertex> Quickly match and perform operations on vertices
- Match<Vertex> matcher: Match matcher that can be used to quickly match and perform operations on vertex sets
Match<[ Vertex ]> $match_vertex_variable; Match<[ Vertex ]> $match_vertex_variable($VertexList);
You can use Match<Vertex> to match or initialize vertex sets.
Match<Vertex> v(['1', '2']); // Directly match by vertex ID. Match<Vertex> v(); // Only Match variables are defined. The vertices to be matched are empty. Match<Vertex> v; v.pattern('match (n:user) where n.age>30 return n limit 10'); // Uses the results of the Cypher statements to match the filtered vertices.
DSL provides a large number of operators for Match<Vertex>, such as pattern, init, and pick. For details, see Match matcher operators.
- Relationship between match matcher and aggregators
You can define an aggregator to hold values and calculations. Each type of matcher can perform operations on its corresponding aggregator in batches.
For example, you can use Match<Vertex> to perform aggregation calculation on a specified vertex set.
Aggregator
- Aggregator description
Aggregators are used to simplify the expression of values during calculation. Different types of aggregators define different scopes of batch aggregation operations.
DSL does not support direct definition of variables of various numeric types to carry data generated during calculation. Instead, DSL provides aggregators to simplify operations in various application scenarios.
- VertexAcc can be used to define additional "properties (variables)" on vertices, and Match<Vertex> can be used to perform operations on additional variables on vertices in batches.
- GlobalAcc can be used to define globally operable variables.
Aggregator declaration syntax: Accumulator<Aggregator Operator, NumericType> v; Parameter description: NumericType: int, (float and double types are not supported currently) Aggregator Operator: Sum,Max,Min
DSL allows you to define different aggregators to simplify algorithm operations. Currently, two types of aggregate variables are supported:
- VertexAcc<Aggregator Operator, type>
- GlobalAcc<Aggregator Operator, type>
You can perform the following operations on an aggregator:
- Initialization: Define an aggregator and assign initial values.
- Assignment: Reset the aggregator values.
- Aggregation: Perform aggregation operations based on defined aggregator operators.
- Aggregator operator description
Different aggregation operations are provided, such as Sum, Max, and Min. Variables are updated using operators + and =.
$match_vertex.$vertex_accumulator += $value; $global_accumulator += $value;
- Vertex aggregator VertexAcc<Aggregator Operator, type>
VertexAcc can be used to quickly define additional "property (variables)" on vertices. and Match<Vertex> can be used to perform operations on additional variables on vertices in batches. This significantly facilitates the calculation process.
VertexAcc<Sum, float> score = 0.5;
Each time a VertexAcc is defined, DSL allocates a variable of the type type to each vertex in the full graph. You can use Match<Vertex> to perform operations on the defined VertexAcc. For example:
VertexAcc<Sum, int> score = 0; // Tom.score = 0, Jack.score = 0 Match<Vertex> v(['Tom', 'Jack']); // Tom.score = 0, Jack.score = 0 v.score += 1; // This operation aggregates the scores of Tom and Jack. That is, their scores are increased by 1. // Tom.score = 1, Jack.score = 1 v.score = 10; //This operation assigns values to the scores of Tom and Jack. That is, their scores are updated to 10. // Tom.score = 10, Jack.score = 10 v.score += 5; // This operation aggregates the scores of Tom and Jack. That is, their scores are increased by 5. // Tom.score = 15, Jack.score = 15
VertexAcc can be operated by expressions. Currently, numeric, GlobalAcc, and VertexAcc expressions can be used for aggregation and assignment.
VertexAcc<Sum, int> score = 0; VertexAcc<Sum, int> factor = 1; GlobalAcc<Sum, int> alpha = 10; Match<Vertex> v(['Tom']); // Tom.score = 0. v.score = alpha x 2 + 3; // This operation assigns a value to Tom's score. // Tom.score = alpha x 2 + 3 = 10 x 2 + 3 = 23 v.score += v.factor*2; // This operation assigns a value to Jack's score. // Tom.score = Tom.score + Tom.factor x 2 = 23 + 1 x 2 = 25
- Global aggregator GlobalAcc<Aggregator Operator, type>
Each time a GlobalAcc is defined, DSL creates a variable of the type type in the DSL scope. Then, perform operations on GlobalAcc directly. For example:
GlobalAcc<Sum, int> diff = 0;// Define a GlobalAcc. diff += 1;// Perform an aggregation operation, that is, diff = Sum (0,1) // diff = 1 diff = 2 x 3;// Assign a value, that is, diff = 2 x 3 // diff = 6 GlobalAcc<Sum, int> g2 = 6;// Define a GlobalAcc. diff += g2;// Perform an aggregation operation, that is, diff = Sum(6,g2) // diff = 12
GlobalAcc can be operated by expressions. Currently, numeric and GlobalAcc expressions can be used for aggregation and assignment.
GlobalAcc<Sum, int> alpha = 0; GlobalAcc<Sum, int> beta= 10; alpha = beta*2+3; // alpha = beta x 2 + 3 = 10 x 2 + 3 = 23
Operator Introduction
Match matcher operators
After a Match matcher is defined, different operation operators, such as repeat, gather, update, and pattern, can be used to assist graph calculation and query.
The operation operator varies with the match type.
Operator |
Description |
Matcher |
Anonymous Expression |
Select/Loop Statement |
---|---|---|---|---|
repeat |
Performs multi-hop filtering like Gremlin. |
Vertex |
× |
× |
pick |
Randomly selects vertices. |
Vertex |
× |
× |
pattern(2.3.11) |
Runs Cypher statements. |
Vertex |
× |
× |
update |
Performs a set of batch operations defined on the matcher. |
Vertex |
√ |
√ |
gather |
Performs a set of batch operations defined on the matcher. |
Vertex |
√ |
√ |
init(2.3.12) |
Initializes the matching vertex set based on a specified ID. |
Vertex |
× |
× |
insert(2.3.12) |
Add new vertices to the matcher. |
Vertex |
× |
× |
move(2.3.12) |
Quickly moves other matcher vertex sets. |
Vertex |
× |
× |
intersection(2.3.12) |
Calculates the intersection of vertices. |
Vertex |
× |
× |
subgraph(2.3.12) |
Obtains guidance subgraphs. |
Vertex |
× |
× |
- repeat
It allows you to perform multi-hop filtering query. The syntax of repeat is similar to that of repeat in Gremlin. Its semantic expression ability is rich, especially suitable for relational link query.
For example, if a two-hop query of filtering name=peter is executed from vertex (1,2) to the outgoing direction, it may be expressed in Gremlin as:
g.V('1','2').repeat(out().has('name','peter')).times(2).emit().dedup()
In DSL, the preceding functions can be written as follows:
Match<Vertex> v(['1','2']); v.repeat(outV().has('name','peter')).times(2).emit();
- The repeat step contains some unique associated steps:
Parameter
Mandatory
Type
Default Value
Description
repeat
Yes
traversal step
None
Executes the repeat rule.
times
No
int
2
Maximum number of steps. The default value is 2, and the maximum value is 20.
emit
No
bool
false
Whether all elements will be returned. The default value is false. If select-as or path is set for output, this parameter determines whether vertices that are not on the final complete path will be returned.
limit
No
int
10000
Number of vertices, edges, or paths.
- Rules in repeat consist of traversal and filter criteria. They can be multiple rules separated by commas (,).
Table 2 Traversal process description Step
Description
outV
Neighbor vertex in the outgoing direction
inV
Neighbor vertex in the ingoing direction
bothV
Neighbor vertex in both directions
outE
Edge in the outgoing direction
inE
Edge in the ingoing direction
bothE
Edge in both directions
otherV
Neighborhood vertex
Table 3 Filter criteria description Filter Criterion
Description
has(key)
Whether the property name key exists
has(key, value)
Whether the value of the property name key is value
hasLabel(values) (V2.3.5)
Whether the label value is one of values
and(filter operator A, filter operator B)
Logical operator of filter criteria. Criteria A and B must be both met. They can be nested.
or(filter operator A, filter operator B)
Logical operator of filter criteria. Either criterion A or B needs to be met. They can be nested.
and(has('person'), or(has('name', 'peter'), has('age', '30'))) has('person') // The property name person exists. has('name', 'peter') // The value of the property name name is peter. hasLabel('movie','user') // The label value is movie or user. and( has('name', 'peter'), has('age', '30')) // The property name is peter and age is 30.
- The repeat step contains some unique associated steps:
- update
$match_vertex.update($lambda_func);
The update operator is used to define a group of batch operations on the matcher. Currently, only Match<Vertex> is supported.
The Update operation on Match<Vertex> applies all operations defined in the input lambda function to the vertices matched by Match.
The vertex matcher Match<Vertex> receives only lambda expressions that contain one input parameter.
Match<Vertex> v(['1',2']); VertexAcc<Max,int> acc=1; GlobalAcc<Sum,int> g=0; v.update( (v1)->{g+=v1.acc*2;} ); //g='1'.acc*2+'2'.acc*2=1*2+1*2=4 return g; // Return g = 4;
- gather
$match_vertex.gather($lambda_func);
The gather operator is used to define a group of batch operations on the matcher. Currently, only Match<Vertex> is supported.
- gather of Match<Vertex>
The Gather operation on Match<Vertex> applies all operations defined in the input lambda function to the edges of the vertices matched by Match.
The vertex matcher Match receives only lambda expressions that contain two input parameters. The first parameter indicates the source vertex on the edge, and the second parameter indicates the target vertex on the edge.Match<Vertex> v(['1',2']); VertexAcc<Max,int> acc=1; GlobalAcc<Sum,int> g=0; v.gather( (s,t)->{g+=s.acc*2+t.acc;} ); // This operation takes effect on the edges of vertices 1 and 2. That is, 1-2, 1-3, 2-3, 2-1. //g=g + 1.acc*2+2.acc + 1.acc*2+3.acc + 2.acc*2+1.acc + 2.acc*2+3.acc //g=0 + 3 + 3 + 3 + 3=12 return g;
- gather of Match<Vertex>
- pick
$match_vertex.pick(n);
pick allows you to randomly select N vertices from Match<Vertex>. This function helps you quickly obtain N random vertices.
Match<Vertex> v(); v.pick(10); // Select 10 vertices randomly from v. return v; // Return information about 10 random vertices.
- init(2.3.12)
$match_vertex.init([vertex_list]); // Specify the vertex ID list. $match_vertex.init(vertexid); // Specify a single ID.
Resets the vertex set of the vertex matcher.
Match<Vertex> v(['1','2']); return v;// Return information about vertices 1 and 2. Match<Vertex> v(['1','2']); v.init(['3','4']); return v;// Return information about vertices 3 and 4.
- insert(2.3.12)
$match_vertex.insert([vertex_list]); // Specify a list of vertex IDs. $match_vertex.insert(vertexid); // Specify a single ID.
Adds a matching vertex set to the vertex matcher.
Match<Vertex> v(['1','2']); return v;// Return information about vertices 1 and 2. Match<Vertex> v(['1','2']); v.insert(['3','4']); return v;// Return information about vertices 1, 2, 3, and 4.
- move(2.3.12)
$match_vertex.move(other_match_vertex);
Quickly moves the vertex set in other_match_vertex to the match_vertex matcher This operator can assign a value to another matcher by one matcher, but does not produce a replication result. Instead, it is similar to the move semantics in C++, that is, moving the original matcher vertex set to the new matcher. After the operation, the original matcher vertex set is cleared.
Match<Vertex> v1(['1','2']); Match<Vertex> v2(['3','4']); v1.move(v2);//v1=[3,4],v2=[] return v1;// Return information about vertices 3 and 4.
- subgraph(2.3.12)
$match_vertex.subgraph();// Return guidance subgraphs of the matcher vertex set. $match_vertex.subgraph(filter_step);// Return guidance subgraphs of the matcher vertex set with edge filtering.
It is mainly used in the return statement. It can return the induced subgraph of the match_vertex vertex matcher.
When obtaining a subgraph, you can set the filter criterion filter_step on the edge. For details about the syntax, see the filter operator in repeat.
Match<Vertex> v(['1','2']); return v.subgraph();// Return vertices 1 and 2 as well as the edge set between vertices 1 and 2. Match<Vertex> v(['1','2','3']); return v.subgraph(has(year, 2022));// Return vertices 1 and 2 as well as the edge set between vertices 1 and 2.
- Set basic operations (2.3.12)
Set operations can be performed on objects in each matcher, such as union and intersection.
intersection (2.3.12)Match<Vertex> start(['1','2']); Match<Vertex> target(['2']); Match<Vertex> set; start.intersection(target); return start;// Return vertex 2.
- Pattern Matching: pattern (2.3.11)
DSL uses the Cypher syntax to express pattern matching, such as vertex set, path, and subgraph matching.
Statements that support Cypher:
Statement
Supported or Not
match(2.3.11)
Partially supported
limit(2.3.11)
Supported
return(2.3.11)
Supported
DSL uses the step-pattern of the Match variable to implement pattern matching.
For example, you need to use a certain rule to match vertices.
Match<Vertex> v; v.pattern('match (n:user) where n.age>30 return n limit 10');
The pattern is a complete Cypher statement, which filters 10 vertices and returns them to Match<Vertex>.
String in Cypher
The pattern syntax contains a complete Cypher statement in single quotation marks. When a string to be expressed, such as an ID or property value, appears in the Cypher statement, double quotation marks are required.
When using REST APIs to call DSL, you need to add the escape character \ to the double quotation marks. For example:
Match<Vertex> v; v.pattern('match (n) where id(n)=\"12\" return n'); return v;
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot