Omnigraph
Queries

Traversal

Follow edges through the graph with single-hop, multi-hop, reverse, and negated traversal patterns.

Traversal patterns let you follow edges between nodes. You write them as $source edgeType $target inside the match block.

Single-hop traversal

Match a direct edge between two nodes:

query friends_of($name: String) {
    match {
        $p: Person { name: $name }
        $p knows $f
    }
    return { $f.name }
}

This finds every Person connected to $p by a Knows edge.

Reverse traversal

Swap the variable positions to traverse in the opposite direction:

query who_knows($name: String) {
    match {
        $target: Person { name: $name }
        $source knows $target
    }
    return { $source.name }
}

This finds people who have a Knows edge pointing to $target.

Sequential multi-hop

Chain multiple traversal patterns to follow paths through the graph:

query friends_of_friends($name: String) {
    match {
        $p: Person { name: $name }
        $p knows $friend
        $friend knows $fof
        $fof.name != $name
    }
    return { $fof.name }
}

Each pattern adds one hop. Variables bind at each step, so you can filter or return intermediate nodes.

Bounded hops

Use {min, max} syntax to specify a range of hops:

query reachable($name: String) {
    match {
        $p: Person { name: $name }
        $p knows{1,3} $reachable
    }
    return { $reachable.name }
}

This finds all Person nodes reachable from $p within 1 to 3 Knows hops.

SyntaxMeaning
edge{2}Exactly 2 hops
edge{1,3}Between 1 and 3 hops
edge{2,}2 or more hops

Chained traversals across types

Traverse through different edge types in sequence:

query colleagues($name: String) {
    match {
        $p: Person { name: $name }
        $p worksAt $c
        $colleague worksAt $c
        $colleague.name != $name
    }
    return { $colleague.name, $c.name }
}

Wildcard variables

Use $_ when you need to traverse an edge but don't care about the target:

query has_connections() {
    match {
        $p: Person
        $p knows $_
    }
    return { $p.name }
}

This returns people who have at least one Knows edge, without binding the other end.

Negation (anti-join)

Use not { } to exclude patterns. A result is returned only if the negated pattern has no matches:

query loners() {
    match {
        $p: Person
        not {
            $p knows $_
        }
    }
    return { $p.name }
}

This finds people with no outgoing Knows edges.

Negation blocks can contain full patterns including traversals and predicates:

query not_at_company($company: String) {
    match {
        $p: Person
        not {
            $c: Company { name: $company }
            $p worksAt $c
        }
    }
    return { $p.name }
}
omnigraph read ./repo.omni \
    --query queries.gq \
    --name loners \
    --json
[
  { "name": "Dave" }
]

On this page