Skip to main content

Querying LoraDB with Cypher

LoraDB speaks a pragmatic subset of Cypher. Queries are strings that chain clauses — see the clause reference below, or jump into the Ten-Minute Tour for a guided run-through.

MATCH  (p:Person)-[:WORKS_AT]->(c:Company)
WHERE  p.active = true
RETURN p.name, c.name
ORDER  BY p.name

Each clause reads the rows emitted by the previous one and passes rows forward. RETURN ends the pipeline.

Anatomy of a query​

MATCH — find patterns (produces rows)
↓
WHERE — filter rows (drops rows)
↓
WITH — project + optionally group (reshapes rows)
↓
WHERE — filter rows post-aggregate (HAVING-style)
↓
RETURN — project + sort + paginate (final shape)

Not every query uses every stage. The important invariant: each clause sees the rows produced by the previous one.

Clause reference​

ClausePurpose
MATCHFind patterns of nodes and relationships
CREATECreate nodes and relationships
WHEREFilter rows
IndexesDeclare, inspect, query, and drop secondary indexes
ConstraintsAdd uniqueness, existence, key, and type checks
RETURN / WITHProject, rename, order, and page results
ORDER BY / SKIP / LIMITSort and paginate
SET / REMOVE / DELETEMutate existing entities
UNWIND / MERGEIterate over lists; create-or-match
Aggregationcount, collect, avg, and group-by
PathsVariable-length traversals and shortest paths

For copy-paste examples covering every clause, see Query Examples. For a single-page terse reference, see the Cheat sheet.

Where common tasks live​

TaskPage
Look up by label + propertyMATCH
Write new nodes/edgesCREATE
UpsertMERGE
Bulk importUNWIND + CREATE
Patch a property mapSET +=
Replace all propertiesSET =
Remove a propertyREMOVE / SET n.p = null
Delete with edgesDETACH DELETE
Top-NORDER BY + LIMIT
Stable paginationKeyset pagination
Group and aggregateAggregation walkthrough
HAVING-style filterWITH … WHERE
Anti-joinNOT EXISTS
Speed up common predicatesCREATE INDEX
Enforce uniqueness or property shapeCREATE CONSTRAINT
Shortest pathshortestPath
Inline related listPattern comprehension
Per-row conditional valueCASE expressions
Count rows matching a conditioncount(CASE WHEN … THEN 1 END)

Execution model​

  • Queries execute atomically per auto-commit call. Rust and in-process bindings also expose explicit transactions; HTTP does not.
  • Auto-commit reads can overlap on Arc snapshots. Write commits and explicit read-write transactions serialize. See Limitations → Concurrency.
  • Names (labels, relationship types, property keys) are never checked against the stored data: CREATE, MERGE, and SET accept any name, and a MATCH on a name nothing carries returns zero rows.
  • Unknown function names are rejected at analysis time — see Functions.

Parameters​

Any value that isn't a constant should use a parameter. The short version follows; Parameters has the full reference.

MATCH (p:Person) WHERE p.name = $name RETURN p

Parameters are bound at call time from the host language:

A parameter missing from the map fails the query before it runs; bind null explicitly for "no value".

Parameters vs inline literals​

// Safe (parameterised)
MATCH (u:User) WHERE u.id = $id RETURN u

;// Unsafe if $id came from untrusted input and was inlined
MATCH (u:User) WHERE u.id = 42 RETURN u

Parameters are the only supported way to mix untrusted input into a query. They also let the query planner cache plans across invocations.

Parameter types​

Host valueLoraDB type
null / None / undefinedNull
boolBoolean
int (Python) / number (JS, integer) / i64 (Rust)Integer
float (Python) / number (JS, non-integer) / f64 (Rust)Float
str / StringString
list / array / VecList
dict / object / BTreeMapMap
host helpers (date(), wgs84(), …)Date, Point, etc.

Host helpers are binding APIs. In query text, use cast syntax for typed construction, for example '2026-05-01'::DATE or {x: 1, y: 2}::POINT.

What's not supported​

See Limitations for the full list. Short version: no general-purpose CALL, no LOAD CSV, and no multi-database (USE). Index and constraint DDL are supported for scoped catalog entries; see Indexes and Constraints.

See also​