Skip to content

openCypher subset

Power queries on a graph-ted-db folder. Everyday open / put / get is the Python store API in Getting started. graph-ted-db also runs a documented subset of openCypher, so graph-ted helper queries and the Graphiti driver can run against a folder. It is not a complete openCypher implementation.

Unsupported syntax raises CypherError with a source position.

Expand the language

For contributors. Do not special-case individual queries. Extend the engine:

Add… Where
A function (labels, coalesce, …) @cypher_fn("name") in graph_ted_db/engine/functions.py. Parser already treats IDENT( as a call.
An aggregating function @cypher_fn("name", aggregating=True) — handler receives the list of per-row values.
A clause (MATCH, WITH, …) Parse it in engine/parser.py parse_clause(), add an AST dataclass in engine/ast.py, register @clause_handler(ThatClause) in engine/executor.py.
A pattern feature NodePattern / RelPattern + Executor.match_pattern.
An operator parse_cmp / parse_add + _binary in engine/eval.py.

Indexes (graph_ted_db.index.LocalIndex) sit under GRAPH_TED_DB_DATA/<graph-id>/index/ (never in the synced folder). MATCH uses the catalog and adjacency list; shards remain the source of truth and are rebuilt on open.

Supported today

Aimed at the queries the graph-ted app and the Graphiti driver send.

Clauses: MATCH, OPTIONAL MATCH, WHERE, WITH [DISTINCT] ORDER BY SKIP LIMIT, UNWIND, RETURN [DISTINCT] ORDER BY SKIP LIMIT, UNION / UNION ALL, DELETE, DETACH DELETE, CREATE, MERGE, SET (property, +=, =, labels, n:$(expr)), CALL db.create.setNodeVectorProperty / setRelationshipVectorProperty, CALL db.index.fulltext.queryNodes / queryRelationships YIELD. CREATE INDEX / CREATE FULLTEXT INDEX / DROP / SHOW are accepted no-ops.

Patterns: (n:Label:Label {prop: expr}), undirected (a)-[r]-(b), directed (a)-[r:TYPE]->(b) / <-, typed [:MENTIONS], anonymous (), -[r]-. An inline map on a relationship (-[r:TYPE {k: expr}]-> or anonymous -[{k: expr}]->) is a filter, same as a node map, including under OPTIONAL MATCH, MERGE, and DELETE. WHERE r.k = $p filters a bound relationship. Variable-length paths (*) are not in this subset.

Expressions: $params, property ., subscript expr[index] (lists, strings, maps), label check n:Entity, AND/OR/NOT, = <> < > <= >=, IN, IS NULL / IS NOT NULL, + (lists append a non-list), CASE WHEN … THEN … ELSE … END, list literals, map literals {k: expr}, list comprehensions [x IN expr WHERE pred].

Functions: labels, type, properties, elementId (also id), coalesce, size, toString, toLower, toUpper, collect [DISTINCT], max, min, count [DISTINCT], count(*) (number of rows), vector.similarity.cosine.

Column names: RETURN expr AS name names a column name. A bare variable is named by the variable (RETURN n → n). Any other expression without AS is named by its source text with whitespace collapsed: RETURN b.name → b.name, RETURN count(*) → count(*). Use AS when a client depends on the name.

Not yet: FOREACH, subqueries, SHORTESTPATH, ranked BM25 fulltext (fulltext is substring token overlap), IN TRANSACTIONS. elementId is the record UUID. Nested objects in props are stored but not walked by . beyond one map.

Node and relationship mapping

openCypher graph-ted-db
Node labels NodeRecord.labels
n.uuid props.uuid if set, else record id
Other n.foo props.foo
Rel type [:MENTIONS] EdgeRecord.type
type(r) / r.name type vs props.name (Graphiti stores HAS_FORM on r.name)
elementId(r) edge record id
DETACH DELETE n delete_node (tombstone node + incident edges)

API

from graph_ted_db import GraphStore, init_graph

init_graph("./my-graph", name="demo", exist_ok=True)
store = GraphStore.open("./my-graph")
store.make_node(labels=["Entity"], props={"name": "Alice", "group_id": "default"})

rows = store.execute(
    "MATCH (n:Entity {group_id: $group_id}) RETURN n.name AS name",
    {"group_id": "default"},
    updated_by="alice",  # optional; default "cypher" on writes
)
graph-ted-db cypher ./my-graph --params '{"group_id":"default"}' \
  'MATCH (n:Entity {group_id: $group_id}) RETURN n.name AS name'

graph-ted-db serve ./my-graph   # http://127.0.0.1:8099  — docs/http.md