Graph Queries

Edge Operations

GRAPH INSERT EDGE IN 'edges' FROM 'alice' TO 'bob' TYPE 'knows' PROPERTIES { since: 2020 };
GRAPH DELETE EDGE IN 'edges' FROM 'alice' TO 'bob' TYPE 'knows';

The IN '<collection>' clause is required — edges are overlays on a named document collection. Statements without IN fail to parse.

Traversal

GRAPH TRAVERSE IN 'edges' FROM 'alice' DEPTH 3;
GRAPH TRAVERSE IN 'edges' FROM 'alice' DEPTH 2 LABEL 'follows' DIRECTION out;
GRAPH TRAVERSE IN 'edges' FROM 'alice' DEPTH 2 LABEL 'follows', 'knows' DIRECTION out;
GRAPH NEIGHBORS IN 'edges' OF 'bob' LABEL 'follows' DIRECTION both;
GRAPH PATH IN 'edges' FROM 'alice' TO 'charlie' MAX_DEPTH 5 LABEL 'knows', 'works_with';
GRAPH TRAVERSE IN 'edges' FROM 'alice' DEPTH 2 LABEL 'follows' EDGE WHERE since >= 2020 AND active = TRUE;
GRAPH PATH IN 'roads' FROM 'a' TO 'z' MAX_DEPTH 6 EDGE WHERE "kind" IN ('road', 'rail') AND NOT (closed = TRUE);

Syntax:

GRAPH TRAVERSE IN '<collection>' FROM '<node>' [DEPTH <n>]
  [LABEL '<label>'[, '<label>' ...]] [DIRECTION in|out|both]
  [EDGE WHERE <predicate>];
GRAPH NEIGHBORS IN '<collection>' OF '<node>'
  [LABEL '<label>'[, '<label>' ...]] [DIRECTION in|out|both];
GRAPH PATH IN '<collection>' FROM '<src>' TO '<dst>' [MAX_DEPTH <n>]
  [LABEL '<label>'[, '<label>' ...]] [EDGE WHERE <predicate>];
  • IN '<collection>' is required. The walk reads only that collection's edges. A statement without IN fails to parse.
  • LABEL takes one or more quoted labels. LABEL 'a', 'b' and LABEL ('a', 'b') are the same.
  • An edge passes when its label is any listed label.
  • An omitted LABEL clause follows every edge.
  • A label no edge carries adds nothing. A list of only such labels follows no edge.
  • LABEL with no quoted label, or with a bare word (LABEL knows), fails with SQLSTATE 42601.
  • DEPTH defaults to 2. MAX_DEPTH defaults to 10. DIRECTION defaults to out.
  • DEPTH or MAX_DEPTH above 64 fails with SQLSTATE 22023.
  • A value above the tenant quota max_graph_depth fails with SQLSTATE 42P17. A quota of 0 sets no limit.

Edge property predicate

EDGE WHERE filters the edges a walk crosses by their properties. Only GRAPH TRAVERSE and GRAPH PATH accept it. Any other GRAPH statement with EDGE WHERE fails to parse.

  • EDGE WHERE is the last clause of the statement.
  • An edge the predicate rejects is not crossed. Its far endpoint is reached only through another edge.
  • Comparisons: =, <>, !=, >, >=, <, <= between a property name and a literal. The literal can stand on either side.
  • IN (...), NOT IN (...), IS NULL, IS NOT NULL.
  • AND, OR, NOT and parentheses combine terms.
  • Literals: NULL, TRUE, FALSE, single-quoted strings, integers, finite floats.
  • An integer literal that does not fit i64 becomes a float.
  • A bare TRUE accepts every edge. A bare FALSE accepts no edge.
  • A property name is one identifier. An unquoted name folds to lower case. Quote it with "…" to keep its case.
  • A missing property compares as follows:
    • = NULL and IS NULL match. = with any other value does not.
    • >, >=, <, <= never match a missing or NULL property.
    • IN never matches. NOT IN always matches.
    • <> and != with a non-NULL literal match. IS NOT NULL does not match.
  • An edge without properties evaluates as an empty object.
  • A comparison between two properties, LIKE, and function calls fail with SQLSTATE 42601.
  • GRAPH PATH tests each edge in its stored direction.

Traversal result

GRAPH TRAVERSE returns one result column holding JSON:

{
  "nodes": [{ "id": "alice", "depth": 0 }, { "id": "bob", "depth": 1 }],
  "edges": [{ "from": "alice", "to": "bob", "label": "follows", "properties": { "since": 2020 } }]
}
  • Each edge carries its current properties. An edge without properties carries {}.
  • Nodes at the last depth are not expanded. Their edges to nodes already in the result are included.

MATCH Pattern Queries

Cypher-subset pattern matching:

MATCH (a:Person)-[:knows]->(b:Person)-[:knows]->(c:Person)
WHERE a.name = 'Alice'
RETURN b.name, c.name;

-- Variable-length paths
MATCH (u:User)-[:follows*2..3]->(rec:User) WHERE u.id = 'you' RETURN DISTINCT rec.id LIMIT 10;

-- Anti-join
MATCH (a:User)-[:follows]->(b:User) WHERE NOT EXISTS { MATCH (b)-[:blocked_by]->(a) } RETURN a.id, b.id;

-- OPTIONAL MATCH
MATCH (a:Person)-[:knows]->(b:Person) OPTIONAL MATCH (b)-[:works_at]->(c:Company) RETURN a.name, b.name, c.name;

Algorithms

GRAPH ALGO PAGERANK ON 'social' DAMPING 0.85 ITERATIONS 20 TOLERANCE 1e-7;
GRAPH ALGO PAGERANK ON 'social' DAMPING 0.85 PERSONALIZATION {"alice": 1.0, "bob": 0.5};
GRAPH ALGO WCC ON 'knowledge_graph';
GRAPH ALGO SSSP ON 'routes' FROM 'city:chicago';
GRAPH ALGO COMMUNITY ON 'products' ITERATIONS 10 RESOLUTION 1.0;
GRAPH ALGO BETWEENNESS ON 'network' SAMPLE 500;
GRAPH ALGO KCORE ON 'collaboration';
GRAPH ALGO TRIANGLES ON 'social' MODE global;
GRAPH ALGO DIAMETER ON 'web';

Available: PAGERANK, WCC, COMMUNITY (or LABEL_PROPAGATION alias), LCC, SSSP, BETWEENNESS, CLOSENESS, HARMONIC, DEGREE, LOUVAIN, TRIANGLES, DIAMETER, KCORE.

Personalized PageRank uses the optional PERSONALIZATION clause to bias node importance toward specified seed nodes. The JSON object maps node IDs to seed weights (higher weight = more biased teleport probability toward that node). Example: PERSONALIZATION {"alice": 1.0, "bob": 0.5} makes PageRank favor paths leading to Alice twice as much as Bob.

GraphRAG

GRAPH RAG FUSION ON entities
  QUERY $embedding VECTOR_FIELD 'embedding' VECTOR_TOP_K 50 EXPANSION_DEPTH 2
  EDGE_LABEL 'related_to' FINAL_TOP_K 10 RRF_K (60.0, 35.0);