The Idea

HelixQL is strongly typed, so you can only traverse edges and access properties that exist in your schema. Select starting points with N or E, then apply traversal steps to walk the graph safely.

::Out   Outgoing Nodes

Return the nodes reached via outgoing edges of a given type.
::Out<EdgeType>

Example 1: Listing who a user follows

QUERY GetUserFollowing (user_id: ID) =>
    following <- N<User>(user_id)::Out<Follows>
    RETURN following

QUERY CreateUser (name: String, handle: String) =>
    user <- AddN<User>({
        name: name,
        handle: handle,
    })
    RETURN user

QUERY FollowUser (follower_id: ID, followed_id: ID, since: Date) =>
    follow_edge <- AddE<Follows>({
        since: since
    })::From(follower_id)::To(followed_id)
    RETURN follow_edge
from helix.client import Client
from datetime import datetime, timezone

client = Client(local=True, port=6969)
since_value = datetime.now(timezone.utc).isoformat()

alice = client.query("CreateUser", {"name": "Alice", "handle": "alice"})
bob = client.query("CreateUser", {"name": "Bob", "handle": "bobby"})

alice_id = alice[0]["user"]["id"]
bob_id = bob[0]["user"]["id"]

client.query("FollowUser", {
    "follower_id": alice_id,
    "followed_id": bob_id,
    "since": since_value,
})

result = client.query("GetUserFollowing", {"user_id": alice_id})
print(result)

::In   Incoming Nodes

Return the nodes that point to the current selection via incoming edges of the given type.
::In<EdgeType>

Example 1: Listing who follows a user

QUERY GetUserFollowers (user_id: ID) =>
    followers <- N<User>(user_id)::In<Follows>
    RETURN followers

QUERY CreateUser (name: String, handle: String) =>
    user <- AddN<User>({
        name: name,
        handle: handle,
    })
    RETURN user

QUERY FollowUser (follower_id: ID, followed_id: ID, since: Date) =>
    follow_edge <- AddE<Follows>({
        since: since
    })::From(follower_id)::To(followed_id)
    RETURN follow_edge
from helix.client import Client
from datetime import datetime, timezone

client = Client(local=True, port=6969)
since_value = datetime.now(timezone.utc).isoformat()

alice = client.query("CreateUser", {"name": "Alice", "handle": "alice"})
bob = client.query("CreateUser", {"name": "Bob", "handle": "bobby"})

alice_id = alice[0]["user"]["id"]
bob_id = bob[0]["user"]["id"]

client.query("FollowUser", {
    "follower_id": alice_id,
    "followed_id": bob_id,
    "since": since_value,
})

result = client.query("GetUserFollowers", {"user_id": bob_id})
print(result)

::OutE   Outgoing Edges

Return the outgoing edges themselves (including properties and endpoints) for the given edge type.
::OutE<EdgeType>

Example 1: Inspecting follow relationships

QUERY GetFollowingEdges (user_id: ID) =>
    follow_edges <- N<User>(user_id)::OutE<Follows>
    RETURN follow_edges

QUERY CreateUser (name: String, handle: String) =>
    user <- AddN<User>({
        name: name,
        handle: handle,
    })
    RETURN user

QUERY FollowUser (follower_id: ID, followed_id: ID, since: Date) =>
    follow_edge <- AddE<Follows>({
        since: since
    })::From(follower_id)::To(followed_id)
    RETURN follow_edge
from helix.client import Client
from datetime import datetime, timezone

client = Client(local=True, port=6969)
since_value = datetime.now(timezone.utc).isoformat()

alice = client.query("CreateUser", {"name": "Alice", "handle": "alice"})
bob = client.query("CreateUser", {"name": "Bob", "handle": "bobby"})

alice_id = alice[0]["user"]["id"]
bob_id = bob[0]["user"]["id"]

client.query("FollowUser", {
    "follower_id": alice_id,
    "followed_id": bob_id,
    "since": since_value,
})

edges = client.query("GetFollowingEdges", {"user_id": alice_id})
print(edges)

::InE   Incoming Edges

Return incoming edges (with properties and endpoints) for the given type.
::InE<EdgeType>

Example 1: Inspecting who followed a user

QUERY GetFollowerEdges (user_id: ID) =>
    follow_edges <- N<User>(user_id)::InE<Follows>
    RETURN follow_edges

QUERY CreateUser (name: String, handle: String) =>
    user <- AddN<User>({
        name: name,
        handle: handle,
    })
    RETURN user

QUERY FollowUser (follower_id: ID, followed_id: ID, since: Date) =>
    follow_edge <- AddE<Follows>({
        since: since
    })::From(follower_id)::To(followed_id)
    RETURN follow_edge
from helix.client import Client
from datetime import datetime, timezone

client = Client(local=True, port=6969)
since_value = datetime.now(timezone.utc).isoformat()

alice = client.query("CreateUser", {"name": "Alice", "handle": "alice"})
bob = client.query("CreateUser", {"name": "Bob", "handle": "bobby"})

alice_id = alice[0]["user"]["id"]
bob_id = bob[0]["user"]["id"]

client.query("FollowUser", {
    "follower_id": alice_id,
    "followed_id": bob_id,
    "since": since_value,
})

edges = client.query("GetFollowerEdges", {"user_id": bob_id})
print(edges)
Combine traversal steps with property filtering or aggregation for richer results. See the Property Access and Aggregations guides.