All Operators
Category |
Operators |
---|---|
Property Reference | . |
Logical Operators | AND , OR , XOR , NOT |
Arithmetic Operators | + , - , * , / , % , ^ |
Comparison Operators | = , <> (or != ), > , < , >= , <= , IN |
Assignment Operators | = |
String Operators | String Concatenation: || (or + )String Matching: CONTAINS Normalized Predicates: IS NORMALIZED , IS NOT NORMALIZED |
List Operators | List Construction: [] Elements Accessing: [] Membership Checking: IN List Concatenation: || |
Path Operators | Path Construction: PATH[] Path Concatenation: || |
Record Operators | Record Construction: RECORD{} Field Reference: . |
Deduplication | DISTINCT |
Exists Predicate | EXISTS |
Null Predicates | IS NULL , IS NOT NULL |
Value Type Predicates | IS TYPED , IS NOT TYPED |
Labeled Predicates | IS LABELED , IS NOT LABELED , : |
Source/Destination Predicates | IS SOURCE OF , IS NOT SOURCE OF , IS DESTINATION OF , IS NOT DESTINATION OF |
Directed Predicates | IS DIRECTED , IS NOT DIRECTED |
Boolean Value Predicates | IS TRUE , IS FALSE |
Precedence Control | () |
Property Reference
The .
(period) allows you to reference a property of a graph element.
MATCH (n)
RETURN n._id LIMIT 10
Logical Operators
AND
Combines two or more conditions in a way that all of them must be true for the entire expression to evaluate to true.
Truth table for the AND
operator:
AND |
True | False |
---|---|---|
True | True | False |
False | False | False |
This query returns users whose age
exceeds 30 and incomeGroup
equals to 4:
MATCH (n:User)
WHERE n.age > 30 AND n.incomeGroup = 4
RETURN n
OR
Combines two or more conditions where only one of them needs to be true for the entire expression to evaluate to true.
Truth table for the OR
operator:
OR |
True | False |
---|---|---|
True | True | True |
False | True | False |
This query returns users whose age
exceeds 30, or incomeGroup
equals to 4:
MATCH (n:User)
WHERE n.age > 30 OR n.incomeGroup = 4
RETURN n
XOR
Combines two or more conditions by evaluating two conditions at a time. For two conditions, the result is true only if exactly one of the conditions is true. If both are true or both are false, the result is false. When applied to multiple conditions, XOR
first evaluates the result of the first two conditions, then compares that result with the next condition, continuing this process until all conditions are checked.
Truth table for the XOR
operator:
XOR |
True | False |
---|---|---|
True | False | True |
False | True | False |
This query returns users whose age
exceeds 30, or incomeGroup
equals to 4, but excludes users who meet both criteria:
MATCH (n:Person)
WHERE n.age > 30 XOR n.incomeGroup = 4
RETURN n
NOT
Negates a condition, returning true if the specified condition is false and vice versa.
Truth table for the NOT
operator:
NOT |
True | False |
---|---|---|
False | True |
This query returns users whose age
is not 30:
MATCH (n:Person)
WHERE NOT n.age = 30
RETURN n
Arithmetic Operators
Performs mathematical operations on numerical values. GQL supports the following arithmetic operators:
- Addition:
+
- Subtraction:
-
- Multiplication:
*
- Division:
/
- Modulus:
%
- Exponentiation:
^
RETURN (2+8)%3
Result:
(2+8)%3 |
---|
1 |
Comparison Operators
Compares two values or expressions and returns true or false. GQL supports the following comparison operators:
- Equal to:
=
- Not equal to:
<>
(or!=
) - Greater than:
>
- Less than:
<
- Greater than or equal to:
>=
- Less than or equal to:
<=
- Belong to:
in
(See Membership Checking)
The operators >
, <
, >=
, and <=
can be used only with numeric, textual, temporal, boolean, and null values.
Comparable Values
In GQL, two values are considered comparable if they can be meaningfully evaluated using comparison operators. There are two kinds of comparable values:
- Essentially Comparable Values: These are values of the same type (e.g., two strings, two dates) or closely related types within the same category (e.g., an integer and a float). They can be directly compared.
- Universally Comparable Values: These include values from different categories that can still be compared by implicitly converting one value’s type to match the other. For example, comparing the integer
12
with the string"13ab"
attempts a conversion before evaluation.
Comparing Numeric Values
RETURN 30.1 > 30 // true
Comparing Textual Values
The first differing character (from left to right) determines the result of the comparison. The characters are compared based on their Unicode values.
RETURN "campus" < "camera" // false
This query returns false
because the first differing character, p
, has a higher Unicode value than e
(Unicode of p
is 112
, while e
is 101
).
Comparing Temporal Values
Temporal values are treated like numeric values, as time is measured in units such as seconds, hours, days, and years. In GQL, the comparison between two temporal values is based on their duration—the difference between the two points in time. If the duration is 0, the values are equal; if negative, the left value is smaller; otherwise, the left value is greater.
// p1.birthday is 1987-10-01, p2.birthday is 1987-10-02
MATCH (p1 {name: "Alex"}), (p2 {name: "Joy"})
RETURN p1.birthday < p2.birthday // true
Comparing List Values
Two lists are considered equal if they contain the same elements in the exact same order.
RETURN [1,2,3] = [1,2,3] // true
RETURN [] = [] // true
RETURN [1,2,3] = [1,3,2] // false
Comparing Records
Two records are considered equal if they have the same fields with identical values.
RETURN {a:1, b:2} = {a:1, b:2} // true
RETURN {a:1, b:2} = {a:2, b:2} // false
RETURN {a:1} = {b:1} // false
Comparing Paths
Paths are similar to lists, as they consist of sequences of nodes and edges.
MATCH p1 = (:User {name: "mochaeach"})-[:Joins]->(:Club {_id: "C02"})
MATCH p2 = (:User {name: "mochaeach"})-[:Joins]->(:Club {_id: "C02"})
RETURN p1 = p2 // true
MATCH p1 = (:User {name: "mochaeach"})-[:Joins]->(:Club {_id: "C02"})
MATCH p2 = (:Club {_id: "C02"})<-[:Joins]-(:User {name: "mochaeach"})
RETURN p1 = p2 // false
Comparing Nodes/Edges
Nodes and edges can be treated like records, where property names act as keys and their corresponding property values serve as values.
MATCH (n1:User {name: "mochaeach"}), (n2:Club {_id: "C02"})
RETURN n1 = n2 // false
Comparing String and Numeric Values
GQL converts a textual value to a numeric value when it is compared with a numeric operand. The conversion process as follows:
- Extract numeric characters: Extracts digits (
0–9
) and any decimal point (.
) from the beginning of the string, stopping at the first non-numeric character. - Convert to numeric type: Converts the extracted numeric portion to the same numeric type as the other operand:
- If the numeric operand is a positive integer, the numeric portion is converted to a
UINT64
. - If the numeric operand is a negative integer (e.g.,
-1
), the numeric portion is converted to anINT64
. - If the numeric operand is a floating-point number (e.g.,
1.0
), the numeric portion is converted to aDOUBLE
.
- If the numeric operand is a positive integer, the numeric portion is converted to a
- If there is no numeric portion at the beginning of the string (i.e., the string does not start with digits or a decimal point), GQL converts it to
0
.
Note: When converting to UINT64
or INT64
, any decimal portion in the extracted numeric portion is discarded.
RETURN 10 > "9a" // true; converts "9a" to 9
RETURN 11.1 < "11.2a" // true; converts "11.2a" to 11.2
RETURN 11 < "11.2a" // false; converts "11.2a" to 11
RETURN 11 < "a10" // false; converts "a10" to 0
Comparing String and Temporal Values
In GQL, strings can be compared with temporal values by implicitly converting the string to a temporal type. This behavior is similar to string-numeric comparisons. For a string to be successfully compared to a temporal value, it must:
- Follow the ISO 8601 standard format for date, datetime, or duration values.
- Be interpreted as a temporal value matching the type of the other operand.
// p.birthday is 1987-10-01
MATCH (p1 {name: "Alex"}), (p2 {name: "Joy"})
RETURN p1.birthday < "1987-10-02" // true
Comparing Boolean Values and Others
Boolean values can be compared with other data types, such as numeric or textual values, through implicit type conversion.
RETURN true = 1 // true
RETURN false = 0 // true
RETURN true = "true" // false
Assignment Operators
The =
operator is used to assign values in statements like LET
and SET
, and to declare path variables within MATCH
statements.
LET a = 1 RETURN a
MATCH (n:Person WHERE n.name = "John Doe")
SET n.gender = "male"
MATCH p = ()->() RETURN p
String Operators
String Concatenation
The ||
(or +
) combines multiple strings into a single string by merging the characters of each string in order.
RETURN "data" || "base"
Result:
"data" || "base" |
---|
database |
String Matching
The CONTAINS
operator checks if one string contains another (case-sensitive).
This query returns user
nodes whose aboutMe
contains "graph database":
MATCH (n:user WHERE n.aboutMe CONTAINS "graph database")
RETURN n
You can transform all letters to upper or lower cases for case-insensitive matching:
MATCH (n:user WHERE lower(n.aboutMe) CONTAINS "graph database")
RETURN n
The CONTAINS
operator is also used to match the specified keywords with tokens of a full-text index (precise or fuzzy match). See Using Full-text Indexes.
This query finds nodes using the full-text index prodDesc
where their tokens include "graph" and "database":
MATCH (n WHERE ~prodDesc CONTAINS "graph database")
RETURN n
Normalized Predicates
Determines whether a character string value is normalized. GQL supports the following normalized predicates:
IS [ <normal form> ] NORMALIZED
IS NOT [ <normal form> ] NORMALIZED
Details
- The
<normal form>
defaults toNFC
. Other available normalization forms areNFD
,NFKC
andNFKD
.
RETURN "Å" IS NORMALIZED AS normRes
Result:
normRes |
---|
1 |
RETURN "Å" IS NFD NORMALIZED AS normRes
Result:
normRes |
---|
0 |
List Operators
List Construction
The []
can create a list by placing comma-separated elements inside.
LET items = [1,2,3]
RETURN items
Result:
items |
---|
[1,2,3] |
The []
can also construct a nested list:
LET items = [[1,2],[2,3]]
RETURN items
Result:
items |
---|
[[1,2],[2,3]] |
Elements Accessing
The []
can access elements within a list by their indexes. Lists use 0-based indexing, meaning the first element is at index 0
.
LET items = ["a", 1, "b"]
RETURN items[0]
Result:
items[0] |
---|
a |
Membership Checking
The IN
checks whether a specified element exists within a list. It evaluates to 1
for true and 0
for false.
This query returns nodes whose _id
can be found in the list of ["U01", "U02"]
:
MATCH (n) WHERE n._id IN ["U01", "U02"]
RETURN n
List Concatenation
The concatenation operator ||
combines multiple lists into a single list by merging the elements of each list in order.
RETURN [1,2,3] || [3,4,5] AS newList
Result:
newList |
---|
[1,2,3,3,4,5] |
Path Operators
Path Construction
The PATH[]
creates a path by enumerating node and edge references in order.
<path value constructor> ::= "PATH[" <path element list> "]"
<path element list> ::= <node reference> [ <path element list step>... ]
<path element list step> ::= "," <edge reference> "," <node reference>
Details
- If
<path element list>
contains the null value or does not identify a path, then an exception condition is raised: Malformed path.
MATCH (n1 {_id: "U01"}), (n2 {_id: "U02"}), -[e {_uuid:39}]->
RETURN PATH[n2, e, n1]
Path Concatenation
The concatenation operator ||
joins multiple paths into a continuous single path, merging the last node of the first path with the first node of the second path when they are identical. If this condition is not met, then an exception condition is raised: Malformed path.
MATCH p1 = ({_id: "U01"})->(n), p2 = (n)->()
RETURN p1 || p2
Note: The expression p1 || p2
returns no result if there is no continuous path in the graph that matches ({_id: "U01"})->(n)->()
. In other words, the concatenation only succeeds when such a full path exists.
Record Operators
Record Construction
The RECORD{}
creates a record by specifying fields.
<record constructor> ::=
[ "RECORD" ] "{" [ <field> [ { "," <field> }... ] ] "}"
<field> ::= <field name> ":" <value expression>
LET rec = RECORD{length: 20, width: 59, height: 10}
RETURN rec.length
Result:
rec.length |
---|
20 |
Field Reference
The .
(period) allows you to reference a field of a record.
LET rec = RECORD{length: 20, width: 59, height: 10}
RETURN rec.length * rec.width * rec.height AS capacity
Result:
capacity |
---|
11800 |
Deduplication
The DISTINCT
ensures that only unique values are included.
This query returns distinct age
values of users:
MATCH (n:User)
RETURN DISTINCT n.age
Exists Predicate
The EXISTS
predicate evaluates whether a specified graph pattern or query returns any results. If it finds matching data, the predicate evaluates to true; otherwise, it evaluates to false. Note that the EXISTS
predicate is not supported in the MATCH
statement.
<exists predicate> ::=
"EXISTS" {
"{" <graph pattern> "}"
| "(" <graph pattern> ")"
| "{" { <match statement>... } "}"
| "(" { <match statement>... } ")"
| <nested query specification>
}
<nested query specification> ::= "{" <query specification> "}"
This query checks whether any path with node A
as source node exists in the graph and returns the result as a boolean:
RETURN EXISTS {({_id:"A"})->()}
This query checks whether there is an edge with score
exceeds 2 exist between nodes A
and B
in the graph and returns the result as a boolean:
RETURN EXISTS {
MATCH ({_id: "A"})-[e]->({_id: "B"})
WHERE e.score > 2
}
This query checks whether any element in a list is greater than 3 and returns the result as a boolean:
RETURN EXISTS {
FOR item in [1,2,3]
FILTER item > 3
RETURN item
}
Null Predicates
Specifies a test for a null value. GQL supports the following null predicates:
IS NULL
IS NOT NULL
This query retrieves the title
of each :Paper
node if the value is not null; otherwise, it returns the message TITLE NOT FOUND
.
MATCH (n:Paper)
RETURN CASE
WHEN n.title IS NOT NULL THEN n.title
ELSE "TITLE NOT FOUND"
END
Value Type Predicates
Determines whether a value conforms to a specific type. GQL supports the following value type predicates:
IS TYPED <value type>
IS NOT TYPED <value type>
Details
- Currently, the
<value type>
supports the following data type keywords:STRING
,BOOL
.
RETURN "a" IS TYPED BOOL AS typeCheck
Result:
typeCheck |
---|
0 |
Labeled Predicates
Determines whether a graph element satisfies a label expression. GQL supports the following value type predicates:
IS LABELED
IS NOT LABELED
:
MATCH (n) WHERE n IS NOT LABELED Paper
RETURN n
MATCH (n) WHERE n:Paper
RETURN n
Source/Destination Predicates
Determines whether a node is the source or destination of an edge. GQL supports the following source/destination predicates:
<node reference> IS SOURCE OF <edge reference>
<node reference> IS NOT SOURCE OF <edge reference>
<node reference> IS DESTINATION OF <edge reference>
<node reference> IS NOT DESTINATION OF <edge reference>
MATCH (n {_id: "P1"}), ()-[e:Cites]->() WHERE n IS SOURCE OF e
RETURN e
Directed Predicates
Directed predicates determine whether an edge variable is bound to a directed edge. GQL supports the following directed predicates:
IS DIRECTED
IS NOT DIRECTED
Details
- All edges created in Ultipa Graph Database are directed.
MATCH ()-[e]-()
RETURN e IS DIRECTED
Result:
e IS DIRECTED |
---|
1 |
Boolean Value Predicates
Evaluates the truthiness of a boolean expression or variable, determining whether it is true or false. GQL supports the following boolean value predicates:
IS TRUE
IS FALSE
RETURN 1 > 2 IS TRUE
Result:
1 > 2 IS TRUE |
---|
0 |