Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Note
This feature is currently in public preview. This preview is provided without a service-level agreement, and isn't recommended for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
This article provides a comprehensive reference for GQL expressions, predicates, and built-in functions available in Fabric Graph queries. Use this reference to understand how to perform calculations, filter results, and transform data in your graph queries.
For an overview of the GQL query language and end-to-end query examples, see GQL language guide. For information about supported data types and literal syntax, see GQL values and value types.
Literals
Literals are simple expressions that directly evaluate to the stated value. The GQL values and value types article explains literals of each kind of value in detail.
Example:
1
1.0d
TRUE
"Hello, graph!"
[ 1, 2, 3 ]
NULL
For detailed literal syntax for each data type, see GQL values and value types.
Predicates
Predicates are boolean expressions that you commonly use to filter results in GQL queries. They evaluate to TRUE, FALSE, or UNKNOWN (null).
Caution
When you use predicates as a filter, they retain only those items for which the predicate evaluates to TRUE.
Comparison predicates
Use these operators to compare values:
=(equal)<>(not equal)<(less than)>(greater than)<=(less than or equal)>=(greater than or equal)
GQL uses three-valued logic where comparisons with null return UNKNOWN:
| Expression | Result |
|---|---|
5 = 5 |
TRUE |
5 = 3 |
FALSE |
5 = NULL |
UNKNOWN |
NULL = NULL |
UNKNOWN |
For specific comparison behavior, see the documentation for each value type in GQL values and value types.
Example:
MATCH (p:Person)
FILTER WHERE p.birthday <= 20050915
RETURN p.firstName
Number coercion rules:
Use the following rules in order of precedence:
- Comparison expressions that involve arguments of approximate numeric types coerce all arguments to be of an approximate numeric type.
- Comparison expressions that involve arguments of both signed and unsigned integer types coerce all arguments to be of a signed integer type.
Logical expressions
Combine conditions with logical operators:
AND(both conditions true)OR(either condition true)NOT(negates condition)
Example:
MATCH (p:Person)
FILTER WHERE p.birthday <= 20050915 AND p.firstName = 'John'
RETURN p.firstName || ' ' || p.lastName AS fullName
Property existence predicates
To check if properties exist, use these predicates:
p.locationIP IS NOT NULL
p.browserUsed IS NULL
Note
Attempting to access a known non-existing property results in a syntax error.
Access to a potentially non-existing property evaluates to null.
The determination of whether a property is known or potentially non-existing
is based on the type of the accessed node or edge.
List membership predicates
Test if values are in lists:
p.firstName IN ['Alice', 'Bob', 'Charlie']
p.gender NOT IN ['male', 'female']
String pattern predicates
Match strings by using pattern matching techniques:
p.firstName CONTAINS 'John'
p.browserUsed STARTS WITH 'Chrome'
p.locationIP ENDS WITH '.1'
Arithmetic expressions
Use standard arithmetic operators with numeric values:
+(addition)-(subtraction)*(multiplication)/(division)
Arithmetic operators follow general mathematical conventions.
Precedence:
Generally, operators follow established operator precedence rules, such as * before +. Use parentheses to control evaluation order as needed.
Example:
(p.birthday < 20050915 OR p.birthday > 19651231) AND p.gender = 'male'
Coercion rules:
Use the following rules in order of precedence:
- Arithmetic expressions involving arguments of approximate number types return a result of an approximate numeric type.
- Arithmetic expressions involving arguments of both signed and unsigned integer types return a result of a signed integer type.
Example:
LET birth_year = p.birthday / 10000
RETURN birth_year
Property access
Access properties by using dot notation:
p.firstName
edge.creationDate
List access
Access list elements by using zero-based indexing:
interests[0] -- first element
interests[1] -- second element
Built-in functions
GQL supports various built-in functions for data processing and analysis.
Aggregate functions
Use aggregate functions to evaluate an expression over a set of rows and get a final result value by combining the values computed for each row. Graph supports the following aggregate functions:
count(*)- counts rowssum(expression)- sums numeric valuesavg(expression)- averages numeric valuesmin(expression)- finds minimum valuemax(expression)- finds maximum valuecollect_list(expression)- collects values into a list
In general, aggregate functions ignore null values and always return a null value when no material input values are provided. You can use coalesce to get a different default value: coalesce(sum(expr), 0). The only exception is the count aggregate function, which always counts the non-null values provided, returning 0 if there are none. Use count(*) to include null values in the count.
Use aggregate functions in three different ways:
- To compute (vertical) aggregates over whole tables
- To compute (vertical) aggregates over subtables determined by a grouping key
- To compute (horizontal) aggregates over the elements of a group list
Vertical aggregates:
-- Vertical aggregate over whole table
MATCH (p:Person)
RETURN count(*) AS total_people, avg(p.birthday) AS average_birth_year
-- Vertical aggregate with grouping
MATCH (p:Person)-[:isLocatedIn]->(c:City)
RETURN c.name, count(*) AS population, avg(p.birthday) AS average_birth_year
GROUP BY c.name
Horizontal aggregates:
Horizontal aggregation computes aggregates over the elements of group list variables from variable-length patterns:
-- Horizontal aggregate over a group list variable
MATCH (p:Person)-[edges:knows]->{1,3}(:Person)
RETURN p.firstName, avg(edges.creationDate) AS avg_connection_date
Horizontal aggregation always takes precedence over vertical aggregation.
To convert a group list into a regular list, use collect_list(edges).
Note
For comprehensive coverage of aggregation techniques including variable-length edge binding and combining horizontal/vertical aggregation, see Advanced Aggregation Techniques.
String functions
char_length(string)- returns string length.upper(string)- returns uppercase variant of provided string (US ASCII only).lower(string)- returns lowercase variant of provided string (US ASCII only).trim(string)- removes leading and trailing whitespace.string_join(list, separator)- joins list elements with separator.
Example:
MATCH (p:Person)
WHERE char_length(p.firstName) > 5
RETURN upper(p.firstName) AS name_upper
Graph functions
nodes(path)- returns nodes from a path value.edges(path)- returns edges from a path value.labels(node_or_edge)- returns the labels of a node or edge as a list of strings.
Example:
MATCH p=(:Company)<-[:workAt]-(:Person)-[:knows]-{1,3}(:Person)-[:workAt]->(:Company)
RETURN nodes(p) AS chain_of_colleagues
List functions
size(list)- returns size of a list value.trim(list,n)- trim a list to be at most of sizen.
Example:
MATCH (p:Person)-[:hasInterest]->(t:Tag)
WHERE size(collect_list(t)) > 3
RETURN p.firstName, collect_list(t.name) AS interests
Temporal functions
zoned_datetime()- returns the current zoned datetime.zoned_datetime("2025-09-12T10:10:52Z")- returns the zoned datetime given by the argument in ISO 8601 format.
Example:
RETURN zoned_datetime() AS now
Generic functions
coalesce(value1, value2, ...)- returns the first non-null value.
Example:
MATCH (p:Person)
RETURN coalesce(p.firstName, 'Unknown') AS display_name