TuringDB home pagelight logodark logo
  • Discord
  • GitHub
  • Website
TuringDB

Get Started

  • Introduction
  • Get Started
  • Claude Code Skill
  • Commands

Concepts

  • Overview
  • A Columnar Graph Database
  • Versioning System
  • The DataPart System
  • Zero-Locking Architecture
  • Snapshots Isolation

Benchmarks

  • Results Summary
  • Technical Report

Query Language

  • Overview
  • Matching
  • Paths
  • Results and Aggregation
  • Subqueries
  • Functions and Types
  • Writing Data
  • Procedures and Commands
  • CheatSheet

Importing data

  • JSONL
  • CSV
  • Neo4j
  • GML
  • Parquet

Graph Development

  • Create Graph
  • Load Graph
  • Load External data
  • Create a Change
  • List Changes
  • Create Nodes and Edges
  • Update Properties
  • Submit a Change
  • Time Travel
  • Graph Examples

Vector Search

  • Vector Search

Graph Algorithms

  • Shortest Path

Tutorials

  • Example Notebooks

Python SDK

  • Get Started
  • Reference

Troubleshooting

  • Troubleshooting

  • MATCH: pattern matching
  • OPTIONAL MATCH
  • WHERE: filter
  • Lookup by native node ID
  • Joins and Cartesian products
  • Variable-length and quantified paths
  • WITH, ORDER BY, SKIP, LIMIT, UNION
  • Aggregation
  • UNWIND, lists, CASE
  • Subqueries
  • Functions
  • Data types
  • Writing (inside a change)
  • Procedures
  • Graph algorithms and search
  • Engine commands
Query Language

TuringDB Query Language Cheatsheet

A compact reference for querying, writing and exploring graphs in TuringDB v3: Cypher plus TuringDB-specific extensions.

Each section links to the page that explains it in full.

​
MATCH: pattern matching

Matching patterns

MATCH (n)
RETURN n

MATCH (n:Person {name: 'Alice'})
RETURN n.age

MATCH (a:Person)-->(b:Company)
RETURN a.name, b.name

MATCH (a:Person)-[e:KNOWS {since: 2010}]->(b:Person)
RETURN a.name, e.since, b.name

MATCH (a)-[r:KNOWS|WORKS_AT]->(b)
RETURN a.name, type(r), b.name

MATCH (a:Person)-[e]-(b)
RETURN a.name, b.name

MATCH (a:Person WHERE a.age > 30)-[r:KNOWS WHERE r.since > 2012]->(b)
RETURN b.name

MATCH (n:Person)
ORDER BY n.age LIMIT 2
RETURN n.name
  • () is a node, [] is an edge, - ignores direction.
  • Node labels use :Label and can be stacked: (n:Person:Employee).
  • Edge types use :EDGE_TYPE: -[:KNOWS]->. An edge has exactly one type, and [:A|B] matches either.
  • RETURN n gives the internal node ID. Return properties explicitly: RETURN n.name.
  • Unknown labels and properties are forgiving: they match nothing or read as null.

​
OPTIONAL MATCH

MATCH (a:Person)
OPTIONAL MATCH (a)-[:WORKS_AT]->(c:Company)
RETURN a.name, c.name

MATCH (a:Person)
OPTIONAL MATCH (a)-[:KNOWS]->(b)
RETURN a.name, count(b)

​
WHERE: filter

MATCH (n)
WHERE n:Person
RETURN n.name

MATCH (n:Person)
WHERE n.age >= 18 AND n.city = 'London'
RETURN n.name

MATCH (n:Person)
WHERE n.name STARTS
WITH 'A' OR n.name CONTAINS 'ro'
RETURN n.name

MATCH (n:Person)
WHERE n.name IN ['Alice', 'Bob']
RETURN n.name

MATCH (n:Person)
WHERE 'admin' IN n.tags
RETURN n.name

MATCH (n:Person)
WHERE n.tags IS NOT NULL
RETURN n.name

MATCH (n)-[e]->(m)
WHERE e:KNOWS AND e.since > 2012
RETURN n.name, m.name

MATCH (p:Person)
WHERE NOT (p)-[:KNOWS]->()
RETURN p.name
  • Comparison: = <> != < <= > >=, null tests IS NULL / IS NOT NULL, boolean AND OR XOR NOT.
  • Strings and lists: IN, STARTS WITH, ENDS WITH, CONTAINS, concatenation with + or ||.
  • Use IS NOT NULL to test for a property (=~ and exists(n.prop) are not yet supported).
  • For Doubles, use ranges (n.score > 1.99 AND n.score < 2.01) or convert with toInteger.

​
Lookup by native node ID

Details

MATCH (n)
WHERE n = 0
RETURN n.name

MATCH (n)-[:KNOWS]->(m)
WHERE n = 0
RETURN m.name

UNWIND [0, 1, 2] AS x
MATCH (n)
WHERE n = x
RETURN id(n), n.name

EXPLAIN MATCH (n)
WHERE n = 0
RETURN n.name
  • Compare the variable (n = 0), not id(n) = 0. The first is a direct seek and the second scans every node.
  • For batches, UNWIND a literal list of distinct IDs and return id(n) rather than x.

​
Joins and Cartesian products

MATCH (p:Person), (c:Company)
RETURN p.name, c.name

MATCH (a:Person)-[:KNOWS]->(b), (b)-[:WORKS_AT]->(c)
RETURN a.name, b.name, c.name

MATCH (a:Person)-->(i:Interest)<--(b:Person)
WHERE a <> b
RETURN a.name, b.name, i.name

MATCH (a:Person), (b:Person)
WHERE a.city = b.city AND a <> b
RETURN a.name, b.name
  • A comma separates independent patterns. Shared variables create joins, unrelated patterns create Cartesian products (N × M rows).

​
Variable-length and quantified paths

Paths

MATCH (a:Person {name: 'Alice'})-[:KNOWS]->+(b)
RETURN DISTINCT b.name

MATCH (a:Person {name: 'Alice'})-[:KNOWS]->*(b)
RETURN DISTINCT b.name

MATCH (a:Person {name: 'Alice'})-[:KNOWS]->{1,2}(b)
RETURN DISTINCT b.name

MATCH (a:Person {name: 'Alice'})-[:KNOWS*1..3]->(b)
RETURN DISTINCT b.name

MATCH (a:Person {name: 'Alice'}) ((x)-[:KNOWS]->(y) WHERE y.age > x.age)+ (b)
RETURN b.name

MATCH p = (a:Person {name: 'Alice'})-[:KNOWS]->+(b)
RETURN [n IN nodes(p) | n.name], length(p)
  • Postfix ->* is 0 or more hops. Bracket -[:KNOWS*]-> is 1 or more.
  • Each edge is used at most once per path. Bound the length on large graphs.

​
WITH, ORDER BY, SKIP, LIMIT, UNION

Results and aggregation

MATCH (n:Person)
WITH n.city AS city, count(*) AS c
WHERE c > 1
RETURN city, c

MATCH (n:Person)
RETURN DISTINCT n.city

MATCH (n:Person)
RETURN n.name, n.age
ORDER BY n.age DESC SKIP 1 LIMIT 2

MATCH (p:Person)
RETURN p.name AS name
UNION
MATCH (c:Company)
RETURN c.name AS name
  • Expressions in WITH must be aliased.
  • Nulls sort last ascending and first descending.

​
Aggregation

MATCH (n:Person)
RETURN count(*), count(n.age), sum(n.age), avg(n.age), min(n.age), max(n.age)

MATCH (a:Person)-[:WORKS_AT]->(c:Company)
RETURN c.name, count(a) AS employees, collect(a.name) AS who

MATCH (n:Person)
RETURN count(DISTINCT n.city)

MATCH ()-[r]->()
RETURN type(r) AS t, count(*) AS c
ORDER BY c DESC
  • Grouping is implicit. To filter on an aggregate, compute it in a WITH and filter afterwards.
  • stdev and percentile* aggregates are not yet available.

​
UNWIND, lists, CASE

UNWIND [1, 2, 3] AS x
RETURN x * 10

MATCH (n:Person)
WITH collect(n.name) AS names
UNWIND names AS nm
RETURN nm

MATCH (n:Person)
UNWIND n.tags AS t
RETURN t, count(*)

RETURN [x IN range(1, 6) WHERE x % 2 = 0 | x * x]

MATCH (a:Person)
RETURN a.name, [(a)-[:KNOWS]->(b) | b.name] AS friends

MATCH (n:Person)
WHERE any(t IN n.tags WHERE t = 'vip')
RETURN n.name

RETURN reduce(total = 0, x IN [1, 2, 3] | total + x)

MATCH (n:Person)
RETURN n.name, CASE WHEN n.age >= 35 THEN 'senior' ELSE 'junior' END AS band

​
Subqueries

Subqueries

MATCH (p:Person)
WHERE EXISTS { (p)-[:WORKS_AT]->(:Company {name: 'Acme'}) }
RETURN p.name

MATCH (p:Person)
RETURN p.name, COUNT { (p)-[:KNOWS]->() } AS outDegree

MATCH (p:Person)
CALL (p) {
  MATCH (p)-[:KNOWS]->(f)
  RETURN f.name AS friend LIMIT 1
}
RETURN p.name, friend

MATCH (p:Person)
OPTIONAL CALL (p) {
  MATCH (p)-[:WORKS_AT]->(c)
  RETURN c.name AS co
}
RETURN p.name, co

​
Functions

Functions and data types

CategoryFunctions
Entityid, labels, type, startNode, endNode
Path and listnodes, relationships, length, size, head, last, tail, reverse, range, reduce
ConversiontoInteger, toFloat, toString, toBoolean, coalesce
StringtoUpper, toLower, trim, ltrim, rtrim, reverse
Mathabs, sign, ceil, floor, round, sqrt, exp, log, log10, pi, e, sin, cos, tan
Temporaldatetime, duration
Embeddingcosine_similarity, euclidean_distance
Aggregatecount, collect, sum, avg, min, max
MATCH (n)-[e]->(m)
RETURN labels(n), type(e), labels(m)

RETURN datetime('2024-03-15T10:30:00Z') + duration({days: 1})

MATCH (n:Document)
RETURN n.title, cosine_similarity(n.emb, (0.4, 0.3, 0.8, 0.1))
  • Function names are case-sensitive, except count and collect.
  • Use type(e) for an edge’s type (it replaces edgeType()).

​
Data types

TypeExample
String'hello' or "hello"
Integer30, 0x1F
Double3.14
Booleantrue
List[1, 'a', [2]]
Map{a: 1}
DateTimedatetime('2024-03-15T10:30:00Z')
Durationduration({days: 2})
Embedding(1.2, 2.0, 0.0) (parentheses, not brackets)

​
Writing (inside a change)

Writing data

CHANGE NEW

CREATE (:Person {name: 'Alice', age: 30})

CREATE (:Person {name: 'Mick'})-[:FRIEND_OF {since: 2020}]->(:Person {name: 'John'})

COMMIT

MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Mick'})
CREATE (a)-[:KNOWS]->(b)

MERGE (n:Person {name: 'Alice'})
  ON CREATE SET n.created = true
  ON MATCH SET n.seen = true

MATCH (n:Person {name: 'Alice'})
SET n.age = 31, n.position = 'Developer'

MATCH (n:Person {name: 'Alice'})
REMOVE n.position

MATCH (n:Person {name: 'Alice'})
DETACH DELETE n

MATCH (n:Person)-[e:KNOWS]->(m)
DELETE e

CHANGE SUBMIT
  • Every node needs at least one label and every edge exactly one type. Labels are set at creation.
  • Run COMMIT after creating entities that a later query must match. CHANGE SUBMIT commits for you.
  • In the Python SDK, call client.checkout() after CHANGE SUBMIT.
  • For more than a few thousand entities, use LOAD PARQUET.

​
Procedures

Procedures and commands

QueryDescription
CALL db.labels()All node labels
CALL db.edgeTypes()All edge types
CALL db.propertyTypes()All property keys and their types
CALL db.history()Commit history
CALL db.describeCommit('<hash>')Counts for a single commit
CALL db.getNodes([0, 1])Labels and all properties of specific nodes
CALL db.procedures()All procedures and signatures

Outputs can be chained: CALL db.labels() YIELD label MATCH (n) WHERE label IN labels(n) RETURN label, count(n).

​
Graph algorithms and search

MATCH (a:Station {name: 'Ashchurch'}), (b:Station {name: 'Pershore'})
shortestPath(a, b, distance, dist, path)
RETURN dist, path

VECTOR SEARCH IN my_index FOR 5 (1.2, 0.5, 3.0, 0.1) YIELD ids, score
RETURN ids, score

See Shortest path and Vector search.

​
Engine commands

CommandDescription
CREATE GRAPH <name>Create a new named graph
LOAD GRAPH <name>Load an existing graph
LOAD GML 'f.gml' AS gLoad a GML file as a graph (file in <turing-dir>/data)
LOAD JSONL 'f.jsonl' AS gLoad a JSONL file as a graph, optionally WITH EMBEDDINGS, WITH DATETIMES, WITH DURATIONS
LOAD PARQUET '<dir>' AS gLoad Parquet files as a graph
LOAD CSV 'f.csv' [WITH HEADERS] [ON ERROR SKIP|FAIL] AS rowStream rows from a CSV file
LIST GRAPH / LIST AVAILABLE GRAPHSLoaded graphs / graphs on disk
CHANGE NEW / SUBMIT / DELETE / LISTCreate, merge, discard and list changes
COMMITSeal pending writes inside a change
LOAD COMMIT '<hash>'Load a past commit (REST API only; the CLI and SDK do it for you)
MERGE_DATAPARTSCompact the graph’s DataParts into one (renumbers nodes)
CREATE VECTOR INDEX <name> WITH DIMENSION <n> METRIC <COSINE|EUCLID>Create a vector index
SHOW VECTOR INDEXES / DELETE VECTOR INDEX <name>List / delete vector indexes
INSTALL <ext> / SHOW EXTENSIONS / SHOW PROCEDURESLoad a procedure extension / list extensions / list procedures
EXPLAIN <query>Show the query plan without running it
Procedures and CommandsJSONL
githublinkedinyoutubediscord