The examples below use the same person / knows / city seed graph as the GQL language tests. SurrealQL snippets return the same or equivalent row shape, but are not a mechanical translation of the GQL compiler; they are idiomatic reads you can compare while learning.
Prerequisites
Start a local instance with GQL enabled and load the seed graph — see GQL via HTTP.
You can run the GQL examples in either of these ways:
| Approach | How |
|---|---|
| HTTP | cURL to POST /gql (shown in each GQL tab) — server needs --allow-experimental gql |
| REPL | eval::gql("…") in surreal sql or Surrealist — also needs --allow-eval-query on the process that runs the engine (embedded surreal sql, or surreal start for remote) |
Example REPL equivalent for the first query:
eval::gql("MATCH (n:person) RETURN n.name AS name ORDER BY name");
-- [{ name: 'A' }, { name: 'B' }, { name: 'C' }]List nodes by label
MATCH (n:person) RETURN n.name AS name ORDER BY namecurl -sS -X POST -u "root:secret" \
-H "Surreal-NS: main" -H "Surreal-DB: main" \
-H "Accept: application/json" -H "Content-Type: text/plain" \
-d 'MATCH (n:person) RETURN n.name AS name ORDER BY name' \
http://localhost:8000/gql[
{ "name": "A" },
{ "name": "B" },
{ "name": "C" }
]Traverse an edge with a property filter
Only person → person knows edges with since > 2020.
MATCH (a:person)-[k:knows]->(b:person)
WHERE k.since > 2020
RETURN a.name, b.name
ORDER BY a.namecurl -sS -X POST -u "root:secret" \
-H "Surreal-NS: main" -H "Surreal-DB: main" \
-H "Accept: application/json" -H "Content-Type: text/plain" \
-d 'MATCH (a:person)-[k:knows]->(b:person) WHERE k.since > 2020 RETURN a.name, b.name ORDER BY a.name' \
http://localhost:8000/gql[
{ "a.name": "A", "b.name": "B" }
]Optional match
Every person, with an optional knows edge to a city when one exists.
MATCH (a:person)
OPTIONAL MATCH (a)-[k:knows]->(b:city)
RETURN a.name AS name, b.name AS city
ORDER BY namecurl -sS -X POST -u "root:secret" \
-H "Surreal-NS: main" -H "Surreal-DB: main" \
-H "Accept: application/json" -H "Content-Type: text/plain" \
-d 'MATCH (a:person) OPTIONAL MATCH (a)-[k:knows]->(b:city) RETURN a.name AS name, b.name AS city ORDER BY name' \
http://localhost:8000/gql[
{ "name": "A", "city": "London" },
{ "name": "B", "city": null },
{ "name": "C", "city": null }
]Aggregation with GROUP BY
Count outgoing person → person knows edges per person.
MATCH (a:person)-[:knows]->(b:person)
RETURN a.name AS name, count(*) AS c
GROUP BY a.name
ORDER BY namecurl -sS -X POST -u "root:secret" \
-H "Surreal-NS: main" -H "Surreal-DB: main" \
-H "Accept: application/json" -H "Content-Type: text/plain" \
-d 'MATCH (a:person)-[:knows]->(b:person) RETURN a.name AS name, count(*) AS c GROUP BY a.name ORDER BY name' \
http://localhost:8000/gql[
{ "name": "A", "c": 1 },
{ "name": "B", "c": 2 },
{ "name": "C", "c": 1 }
]What to try next
The language-test corpus under language-tests/tests/opengql/ in the SurrealDB repository covers variable-length quantifiers (->{1,3}, ->*), path search (ALL SHORTEST, SHORTEST k), multi-pattern comma joins, and mutations. Variable-length and path patterns have no single-line SurrealQL equivalent — they are the main reason to reach for GQL for reads; mutations are the ISO-native way to change graph data in the same program as MATCH.