A standards distinction matters: ISO/IEC 39075:2024 standardizes GQL for property graphs and includes graph pattern matching and path queries. The
bif:analytics functions in these examples are Virtuoso extensions; they are not functions specified by ISO GQL. The path pattern examples near the end use GQL path matching, while the analytics calls use Virtuoso’sbif:functions.
The examples query the urn:social graph and use foaf:knows relationships. Run links open the supplied queries at the VEC endpoint.
PageRank and centrality
PageRank ranks nodes by the link structure of the selected graph. With RDF 1.2 edge annotations, the first example uses an edge weight. The following examples show unweighted PageRank, parameterized PageRank, and four centrality measures.
Weighted PageRank via RDF 1.2 edge annotations
GQL
PREFIX ex: <#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
VERSION "rdf 1.2"
USE GRAPH <urn:social>
MATCH (p)-[e:foaf:knows {ex:weight: w}]->(other)
RETURN DISTINCT p,
bif:GRAPH_PAGERANK_WEIGHTED(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows'),
iri('#weight')
) AS score
ORDER BY score DESC
Basic PageRank
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:pagerank(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
) AS score
ORDER BY score DESC
PageRank with damping, iteration limit, and tolerance
This example sets a damping factor of 0.9, a maximum of 500 iterations, and a tolerance of 0.000001.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:pagerank(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows'),
0.9,
500,
0.000001
) AS score
ORDER BY score DESC
Degree centrality
Degree centrality counts a node’s connections. This query asks for the measure in both directions.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:degree_centrality(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows'),
'both'
) AS score
ORDER BY score DESC
Betweenness centrality
Betweenness centrality scores nodes by their role along paths between other nodes. The arguments specify the graph, relationship type, normalization, and direction settings.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:betweenness(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows'),
1,
0
) AS score
ORDER BY score DESC
Closeness centrality
Closeness centrality measures how near a node is to the other nodes, based on paths through the graph.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:closeness(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
) AS score
ORDER BY score DESC
Eigenvector centrality
Eigenvector centrality gives greater weight to connections with nodes that themselves score highly. This example supplies an iteration limit and tolerance.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:eigenvector(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows'),
200,
0.00001
) AS score
ORDER BY score DESC
Components, communities, and triangles
These queries group nodes by connectivity or community assignment, or count triangles involving each node.
Weakly connected components (WCC)
WCC groups nodes by connectivity while disregarding edge direction.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:wcc(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
) AS score
ORDER BY score DESC
Strongly connected components (SCC)
SCC retains direction: nodes are grouped when directed paths connect them both ways.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:scc(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
) AS score
ORDER BY score DESC
Community ID (Louvain)
This query returns a community identifier for each matched node.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:community_id(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
) AS score
ORDER BY score DESC
Triangles
Triangle counts show how many closed three-node patterns include each node.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (p)-[:foaf:knows]-(other)
RETURN DISTINCT p,
bif:triangle_count(
p,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
) AS score
ORDER BY score DESC
Match and measure paths
GQL path patterns can express reachability and shortest-path matches. The next examples fix Alice as the starting node and Eve as the destination, then return either a path match, its length, or a serialized route.
Shortest-path matching with GQL
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH SHORTEST PATH (a)-[:foaf:knows*]->(b)
WHERE a = iri('#alice') AND b = iri('#eve')
RETURN a, b
Shortest-path length: Alice to Eve
This query returns the hop count as well as the endpoints.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (a)-[:foaf:knows*]->(b)
WHERE a = iri('#alice') AND b = iri('#eve')
RETURN DISTINCT a, b,
bif:shortest_path_length(
a,
b,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
) AS hops
Run the Alice-to-Eve path-length query.
Shortest route: return the node sequence
The route function returns the node sequence; sql:obj2json serializes it as JSON for display.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (a)-[:foaf:knows*]->(b)
WHERE a = iri('#alice') AND b = iri('#eve')
RETURN DISTINCT
sql:obj2json(
bif:shortest_path(
a,
b,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows')
)
) AS route
Cheapest weighted route and total cost
The weighted shortest-path function returns an array-like result. The query converts its route element to JSON and reads the total cost from element 2.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (a)-[:foaf:knows*]->(b)
WHERE a = iri('#alice') AND b = iri('#eve')
LET result = bif:GRAPH_SHORTEST_PATH_WEIGHTED(
a,
b,
iri('urn:social'),
iri('http://xmlns.com/foaf/0.1/knows'),
iri('#weight'),
1
)
RETURN DISTINCT
sql:obj2json(bif:aref(result, 0)) AS route,
bif:aref(result, 2) AS cost
Run the cheapest weighted-route query.
Path finding: everyone reachable from Alice
The + quantifier requires one or more foaf:knows edges, returning nodes reachable from Alice.
GQL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
USE GRAPH <urn:social>
MATCH (a)-[:foaf:knows+]->(b)
WHERE a = iri('#alice')
RETURN DISTINCT b
Run the Alice reachability query.
Queries and analytics in one graph workflow
The examples show two related capabilities: GQL patterns express graph matches and paths, while Virtuoso’s bif: functions add graph analytics over the RDF relationships. Their combination keeps the data pattern, selected graph, analytics operation, and returned result visible in query text.
The analytics function names and parameters shown here are Virtuoso-specific. Their presence in a GQL query does not make them part of ISO GQL; implementations can provide different analytics functions and interfaces. The RDF 1.2 edge-annotation example likewise relies on the endpoint’s RDF 1.2 support.
These examples extend the original RDF graph-analytics article from SPARQL query patterns to GQL query text, including standard path matching and Virtuoso analytics extensions.
