Built-in Functions in LoraDB
Functions are expressions. You can use them anywhere an expression is
accepted: in RETURN, WITH, WHERE, ORDER BY, SET, map
projections, list comprehensions, and nested inside other function
calls.
MATCH (d:Doc)
WITH d,
vector.similarity(d.embedding, $query) AS score,
temporal.truncate('month', d.published_at) AS month
WHERE score >= 0.75
RETURN d.title, month, score
ORDER BY score DESC
LIMIT 10Function names are case-insensitive. Canonical LoraDB functions are
mostly namespaced, such as string.lower, math.sqrt, list.range,
temporal.now, geo.distance, vector.similarity, type.of, and
cast.try. A small set of historical and convenience aliases remains
for common Cypher-style helpers and zero-argument value helpers, such as
toInteger, toString, size, head, length, coalesce, and
now.
The analyzer resolves every function call before execution. That means unknown names, wrong argument counts, unknown type literals, and invalid enum literals such as vector metric names are rejected before rows are scanned. The executor then evaluates only validated calls.
Most functions propagate null — any null argument makes the
result null. The exceptions are aggregates, coalesce, current-time
helpers, and constants/random helpers.
Function expression basics
Functions do not introduce a new query clause. They are part of the expression language, so they evaluate once for each row flowing through the clause that contains them.
MATCH (u:User)
WITH u, string.lower(u.email) AS email
WHERE email ENDS WITH '@loradb.com'
RETURN u.name, email
ORDER BY emailIn that query:
string.lower(u.email)runs for each matchedUserrow.WITHgives the result a name so later clauses can reuse it.WHERE,RETURN, andORDER BYall see the shaped row fromWITH.
Functions are side-effect free. They cannot create nodes, update
properties, query indexes by themselves, or change the graph. Graph
writes still happen through clauses such as CREATE, MERGE, SET,
and DELETE; functions only compute values for those clauses to use.
Reading signatures and examples
Function pages use compact signatures:
| Notation | Meaning |
|---|---|
fn(x) | one required argument |
fn(x[, y]) | y is optional |
fn(a, b, ...) | accepts a variable number of arguments |
LIST<T> | a list whose elements are usually the same type |
null → null | a null input returns null instead of an error |
Examples are written as complete Cypher fragments whenever possible. Comments show representative results, not a promise about exact display format in every host binding.
RETURN string.slice('loradb', 0, 4); // 'lora'
RETURN '2024-01-15'::DATE; // DATE value
RETURN TRY_CAST('not a date' AS DATE) // nullHow functions are organised
LoraDB keeps value construction and value operations separate:
| Use case | Preferred syntax | Why |
|---|---|---|
| Build a typed value in query text | '2024-01-15'::DATE, {x: 1, y: 2}::POINT, [1,2,3]::VECTOR<INTEGER>(3) | Casts make the target type explicit. |
| Convert with CAST syntax | CAST(value AS TYPE) | First-class Cypher grammar for strict conversion. |
| Convert without throwing | TRY_CAST(value AS TYPE) | Nullable cast; returns null when conversion fails. |
| Ask about a value's type | type.of(value) | Returns tags such as "DATE" or "VECTOR<FLOAT32>(384)". |
| Work with temporal values | temporal.now(), temporal.truncate('month', d) | Current-time helpers and temporal operations. |
| Work with points | geo.distance(a, b), geo.within_bbox(p, ll, ur) | Spatial operations over existing POINT values. |
| Work with vectors | vector.similarity(a, b), vector.distance(a, b, EUCLIDEAN) | Vector math over existing VECTOR values. |
The important distinction: temporal.*, geo.*, and vector.* are
operation namespaces. They are not the default way to construct
DATE, POINT, or VECTOR values in query text.
RETURN '2024-01-15'::DATE,
CAST('2024-01-15' AS DATE),
TRY_CAST($maybe_date AS DATE)Use host-language helpers separately when binding parameters from
Node, Python, Go, Ruby, WASM, or Rust. For example, a Node query may
bind { at: datetime("2026-05-01T09:00:00Z") }, but the equivalent
query-text literal is '2026-05-01T09:00:00Z'::DATETIME.
Choosing a construction form
Use the form that best matches where the value comes from:
| Source value | Recommended query syntax | Notes |
|---|---|---|
| Literal ISO date/time text | '2026-05-01'::DATE | Most readable for handwritten queries. |
| Literal map point | {longitude: 4.89, latitude: 52.37}::POINT | Lets the POINT cast validate CRS/SRID rules. |
| Literal numeric vector | [0.1, 0.2, 0.3]::VECTOR<FLOAT32>(3) | Dimension and coordinate type are visible at the use site. |
| Parameter that may be invalid | TRY_CAST($value AS DATE) | Returns null, so pair it with IS NOT NULL or coalesce. |
| Generated query text | CAST($value AS DATE) | Strict conversion using the Cypher grammar. |
Strict casts are useful when bad input should stop the query. TRY_CAST
is better for ingestion and optional filters, where a failed conversion
should become null and be handled by normal Cypher predicates.
The older constructor-shaped temporal, spatial, and vector forms are not the preferred public query syntax. Use casts in query text, and use client-library binding helpers only when creating parameters in a host language.