NornicDB Complete Functions Index
documentation with real-world examples
Last Updated: November 25, 2025
Quick Navigation
Detailed Function Docs - Complete guides with examples Memory Decay System - How memory fading works Status: 52 functions documented (100% coverage)
All Functions by Category
Node & Relationship Functions (11 functions)
| Function | What It Does | Example |
|---|---|---|
id(n) | Get unique ID | MATCH (n) RETURN id(n) |
elementId(n) | Neo4j-compatible ID | RETURN elementId(n) |
labels(n) | Get node labels/types | RETURN labels(n) |
type(r) | Get relationship type | MATCH ()-[r]->() RETURN type(r) |
keys(n) | List property names | RETURN keys(n) |
properties(n) | Get all properties | RETURN properties(n) |
startNode(r) | Get relationship start node | RETURN startNode(r) |
endNode(r) | Get relationship end node | RETURN endNode(r) |
nodes(path) | Get nodes in path | RETURN nodes(path) |
relationships(path) | Get rels in path | RETURN relationships(path) |
exists(n.prop) | Check if property exists | WHERE exists(n.email) |
String Functions (20 functions)
| Function | What It Does | Example |
|---|---|---|
toString(val) | Convert to string | RETURN toString(42) |
toLower(s) | Convert to lowercase | RETURN toLower("HELLO") |
toUpper(s) | Convert to UPPERCASE | RETURN toUpper("hello") |
trim(s) | Remove edge whitespace | RETURN trim(" hi ") |
ltrim(s) | Trim left side | RETURN ltrim(" hi") |
rtrim(s) | Trim right side | RETURN rtrim("hi ") |
replace(s, find, repl) | Find & replace | RETURN replace("cat", "c", "b") |
split(s, delim) | Split into list | RETURN split("a,b,c", ",") |
substring(s, start, len) | Extract substring | RETURN substring("hello", 0, 3) |
left(s, n) | First n characters | RETURN left("hello", 2) |
right(s, n) | Last n characters | RETURN right("hello", 2) |
size(s) | String/list length | RETURN size("hello") |
char_length(s) | Character count | RETURN char_length("hi") |
normalize(s) | Unicode normalization | RETURN normalize(s) |
btrim(s, chars) | Trim specific chars | RETURN btrim("!!hi!!", "!") |
The string.* namespace (Cypher 25 functions, also accepted under Cypher 5):
| Function | What It Does | Example |
|---|---|---|
string.indexOf(s, value) | Character index of value in s, or -1 | RETURN string.indexOf("hello", "l") |
string.join(list, delimiter) | Join a list of strings | RETURN string.join(["a", "b"], "-") |
string.regexReplace(s, re, repl) | Replace every match of a regular expression | RETURN string.regexReplace("a b", "\s+", " ") |
Type Conversion Functions (4 functions)
| Function | What It Does | Example |
|---|---|---|
toInteger(val) | Convert to integer | RETURN toInteger("42") |
toInt(val) | Alias for toInteger | RETURN toInt("42") |
toFloat(val) | Convert to decimal | RETURN toFloat("3.14") |
toBoolean(val) | Convert to true/false | RETURN toBoolean("true") |
Mathematical Functions (7 functions)
| Function | What It Does | Example |
|---|---|---|
abs(x) | Absolute value | RETURN abs(-5) |
ceil(x) | Round up | RETURN ceil(3.2) |
floor(x) | Round down | RETURN floor(3.8) |
round(x) | Round normally | RETURN round(3.5) |
sign(x) | Get sign (-1/0/1) | RETURN sign(-5) |
sqrt(x) | Square root | RETURN sqrt(16) |
rand() | Random 0-1 | RETURN rand() |
Trigonometric Functions (11 functions)
| Function | What It Does | Example |
|---|---|---|
sin(x) | Sine | RETURN sin(radians(90)) |
cos(x) | Cosine | RETURN cos(radians(0)) |
tan(x) | Tangent | RETURN tan(radians(45)) |
cot(x) | Cotangent | RETURN cot(radians(45)) |
asin(x) | Arc sine | RETURN asin(0.5) |
acos(x) | Arc cosine | RETURN acos(0.5) |
atan(x) | Arc tangent | RETURN atan(1) |
atan2(y, x) | 2-arg arc tangent | RETURN atan2(y, x) |
radians(deg) | Degrees→radians | RETURN radians(180) |
degrees(rad) | Radians→degrees | RETURN degrees(3.14) |
haversin(x) | Haversine | RETURN haversin(x) |
Advanced Math Functions (4 functions)
| Function | What It Does | Example |
|---|---|---|
exp(x) | e^x | RETURN exp(1) |
log(x) | Natural log | RETURN log(2.718) |
log10(x) | Base-10 log | RETURN log10(100) |
pi() | π constant | RETURN pi() |
e() | e constant | RETURN e() |
List Functions (17 functions)
| Function | What It Does | Example |
|---|---|---|
size(list) | List length | RETURN size([1,2,3]) |
head(list) | First element | RETURN head([1,2,3]) |
last(list) | Last element | RETURN last([1,2,3]) |
tail(list) | All except first | RETURN tail([1,2,3]) |
reverse(list) | Reverse order | RETURN reverse([1,2,3]) |
range(start, end, step) | Create number sequence | RETURN range(1, 10, 2) |
coalesce(v1, v2, ...) | First non-null value | RETURN coalesce(null, 5, 10) |
reduce(...) | Reduce list to value | See examples below |
isEmpty(x) | Check if empty | RETURN isEmpty([]) |
The coll.* functions of Cypher 25 (Neo4j 2026.09; NornicDB has them in Cypher 5 statements too). They order values as ORDER BY does (null after everything) and tell them apart as DISTINCT does (1 and 1.0 are one value). A null list, index or depth gives null.
| Function | What It Does | Example |
|---|---|---|
coll.distinct(list) | Duplicates removed, first kept | RETURN coll.distinct([1, 1.0, 2]) → [1, 2] |
coll.flatten(list [, depth]) | Nested lists spliced in, depth levels (default 1) | RETURN coll.flatten([1, [2, [3]]], 2) → [1, 2, 3] |
coll.indexOf(list, value) | Index of the first equal item, or -1 | RETURN coll.indexOf([1, 2], 2) → 1 |
coll.insert(list, index, value) | value inserted before list[index] (0 to size) | RETURN coll.insert([1, 3], 1, 2) |
coll.remove(list, index) | list without list[index] | RETURN coll.remove([1, 2, 3], 0) |
coll.max(list) / coll.min(list) | Greatest / least item in ORDER BY order | RETURN coll.max([3, 1, 2]) → 3 |
coll.sort(list) | Sorted in ORDER BY order | RETURN coll.sort([3, 'a', 1]) → ['a', 1, 3] |
An index or depth out of range, and coll.remove on an empty list, are ArgumentErrors, as in Neo4j.
Vector Functions (2 functions)
| Function | What It Does | Example |
|---|---|---|
vector.similarity.cosine(v1, v2) | Cosine similarity, in [0, 1] | RETURN vector.similarity.cosine([1,2,3], [2,3,4]) |
vector.similarity.euclidean(v1, v2) | Euclidean similarity, in [0, 1] | RETURN vector.similarity.euclidean([0,0], [3,4]) |
Both return Neo4j's scores, bit for bit: cosine is max((1 + cos) / 2, 0) (1 for the same direction, 0.5 for orthogonal vectors, 0 for opposite ones) and euclidean is 1 / (1 + d²) (1 for equal vectors), computed in float32. db.index.vector.queryNodes and queryRelationships score on the same scale for COSINE and EUCLIDEAN indexes (a dot index, a NornicDB similarity, scores the dot product). Null in, null out; an argument that isn't a list is a TypeError; an empty list, a list holding a non-number or a non-finite number, a zero vector (cosine) or vectors of different dimensions are an ArgumentError, as in Neo4j.
VECTOR and UUID values (Cypher 25). vector(value, dimension, coordinateType) builds a VECTOR of INTEGER64 (INTEGER), INTEGER32, INTEGER16, INTEGER8, FLOAT64 (FLOAT) or FLOAT32 coordinates from a list of numbers or its text; uuid() is a random version 7 UUID. Both can be stored as properties, compared with =, sorted, and tested with IS :: VECTOR<INTEGER>(3) / IS :: UUID. A vector is not a list: toIntegerList, toFloatList and size read it. Bolt 5 clients receive both as the placeholder map {reason: 'UNKNOWN_TYPE', originalType: 'VECTOR(3, INTEGER64)'} (or 'UUID'), as Neo4j sends them; the HTTP API writes a UUID as its text.
| Function | What It Does | Example |
|---|---|---|
vector(value, dimension, type) | A VECTOR | RETURN vector([1, 2, 3], 3, INTEGER) |
vector_dimension_count(v) | Its dimension | RETURN vector_dimension_count(vector([1, 2], 2, FLOAT)) |
vector_distance(a, b, metric) | Distance by EUCLIDEAN, EUCLIDEAN_SQUARED, MANHATTAN, COSINE, DOT or HAMMING | RETURN vector_distance(vector([1, 2], 2, FLOAT), vector([2, 4], 2, FLOAT), EUCLIDEAN) |
vector_norm(v, metric) | Distance to the origin by EUCLIDEAN or MANHATTAN | RETURN vector_norm(vector([3, 4], 2, INTEGER), EUCLIDEAN) |
uuid() / uuid(text) / uuid(msb, lsb) | A UUID | RETURN toString(uuid(1, 2)) |
uuid.mostSignificantBits(u) / uuid.leastSignificantBits(u) | Its halves as integers | RETURN uuid.mostSignificantBits(uuid()) |
uuid.v5(namespace, name) | The version 5 (name-based) UUID of name in namespace (a UUID or its text): the same arguments always give the same UUID, so MERGE can deduplicate on it. A NornicDB extension. | RETURN toString(uuid.v5('6ba7b810-9dad-11d1-80b4-00c04fd430c8', 'python.org')) |
Kalman Filter Functions (10 functions)
Real-time signal filtering and prediction for time series data. Perfect for smoothing noisy sensor readings, tracking market sentiment, or predicting trends.
| Function | What It Does | Example |
|---|---|---|
kalman.init(config?) | Create basic filter state | RETURN kalman.init() |
kalman.process(val, state, target?) | Filter a measurement | kalman.process(23.5, s.state) |
kalman.predict(state, steps) | Predict future value | kalman.predict(s.state, 5) |
kalman.state(state) | Get current estimate | kalman.state(s.state) |
kalman.reset(state) | Reset filter | kalman.reset(s.state) |
kalman.velocity.init(pos?, vel?) | Create trend-tracking filter | kalman.velocity.init() |
kalman.velocity.process(val, state) | Filter with velocity tracking | Returns {value, velocity, state} |
kalman.velocity.predict(state, steps) | Predict with momentum | kalman.velocity.predict(s.state, 5) |
kalman.adaptive.init(config?) | Create auto-switching filter | kalman.adaptive.init() |
kalman.adaptive.process(val, state) | Filter with auto mode-switch | Returns {value, mode, state} |
Text Location (1 function, a NornicDB extension)
text.locate(text, quote, options) returns {start, end}, the span of a quote's best occurrence in text in code points (substring(text, start, end - start) is the passage), or null. The quote's words match in order, as a reader copies a quote: without case; with any run of whitespace, JSON escapes (\n, \r, \t, as a JSON file's one-line body has them) or a reply's > markers after a line break between them (a > in the quote matches one literally); typographic and plain quotation marks (', "), apostrophes and dashes alike; markdown emphasis (*, **, _, __) and link markup ([label](/api-reference/cypher-functions/target)) allowed around a word, never inside one, so filename doesn't match file_name. The span is the text's own, markup around its first and last words included. In the quote, a copied line label (12: ) and JSON escapes are dropped.
| Option | Meaning |
|---|---|
line | The 1-based line the quote was cited on: the occurrence starting on it wins, else the nearest within tolerance lines (the lower line first on a tie), else null. A line that isn't one of the text's is null. Without it, the first occurrence wins. |
tolerance | Lines around line an occurrence may start on (default 3). |
from, to | The code-point range the occurrence must lie in. |
MATCH (s:Source {id: $id})
RETURN text.locate(s.text, $quote, {line: $line, from: $partStart, to: $partEnd}) AS spanTo place many quotes in one long text passed as a parameter, bind it once (WITH $text AS t UNWIND $citations AS c RETURN text.locate(t, c.quote, {line: c.line})): a string parameter used directly in the per-row expression is re-read on every row.
Text intervals and line positions in Cypher
Spans stored as parallel lists (starts, ends and metadata such as labels or roles, half-open [start, end) in code points, as substring and text.locate count) need no function of their own. These statements return the same rows in Neo4j.
Run the partition statement after a MATCH that binds s, for example MATCH (s:Source {id: $id}), with parameters start and end. Its lists may be unordered and overlapping: the interval with the earliest start owns the overlap, with the lower list index winning equal starts. A later interval contributes only its uncovered suffix. Empty intervals are ignored; empty or absent lists leave the whole span as 'own'. The extra empty interval in the statement preserves a row for that case.
// Intervals overlapping [start, stop), clipped to it, in list order with index and metadata;
// an empty span [start, start) stands for [start, start + 1)
WITH s, $start AS start, CASE WHEN $end > $start THEN $end ELSE $start + 1 END AS stop
RETURN [i IN range(0, size(coalesce(s.starts, [])) - 1)
WHERE s.starts[i] < stop AND start < s.ends[i]
| {index: i, start: CASE WHEN start > s.starts[i] THEN start ELSE s.starts[i] END,
end: CASE WHEN stop < s.ends[i] THEN stop ELSE s.ends[i] END, label: s.labels[i]}] AS overlaps
// [start, end) split into the intervals' clipped parts with their role, gaps as 'own'
WITH s, $start AS start, $end AS end
UNWIND [i IN range(0, size(coalesce(s.starts, [])) - 1) |
{start: s.starts[i], end: s.ends[i], role: s.roles[i], index: i}]
+ [{start: end, end: end, index: -1}] AS part
WITH s, start, end, part ORDER BY part.start, part.index
WITH s, start, end, collect(part) AS intervals
WITH start, end, reduce(acc = {position: start, parts: []}, part IN intervals |
CASE WHEN start >= end OR part.start >= part.end OR part.start >= end OR part.end <= acc.position THEN acc
ELSE {position: CASE WHEN part.end < end THEN part.end ELSE end END,
parts: acc.parts
+ CASE WHEN acc.position < part.start
THEN [{start: acc.position, end: part.start, role: 'own'}]
ELSE [] END
+ [{start: CASE WHEN part.start > acc.position THEN part.start ELSE acc.position END,
end: CASE WHEN part.end < end THEN part.end ELSE end END, role: part.role}]}
END) AS acc
RETURN acc.parts + CASE WHEN acc.position < end THEN [{start: acc.position, end: end, role: 'own'}] ELSE [] END AS parts
// The 1-based line, 0-based column and line text at a code-point offset
WITH text, offset, substring(text, 0, offset) AS before
WITH text, before, size(before) - size(replace(before, '\n', '')) AS breaks
RETURN breaks + 1 AS line, size(last(split(before, '\n'))) AS column, split(text, '\n')[breaks] AS context
// A span's lines as "n: line", numbered from first ('' gives "first: ")
WITH split(substring(text, $start, $end - $start), '\n') AS lines, $first AS first
RETURN reduce(out = '', i IN range(0, size(lines) - 1) |
out + CASE WHEN i = 0 THEN '' ELSE '\n' END + toString(first + i) + ': ' + lines[i]) AS numberedEach overlap list scans all intervals, so a span costs O(intervals). For many spans over one source, bind the lists once (WITH s.starts AS starts, s.ends AS ends UNWIND $spans AS q …).
APOC digests
apoc.util.sha256(values), apoc.util.sha1(values) and apoc.util.md5(values) are built in. They return the lower-case hex digest of the values' Java string forms concatenated; null list elements add nothing. For example, apoc.util.sha256(['a', 'b', null, 'c']) hashes the UTF-8 text abc. The bundled APOC handlers use the same implementation.
Date/Time Functions (4 functions)
| Function | What It Does | Example |
|---|---|---|
timestamp() | Current Unix timestamp (ms) | RETURN timestamp() |
datetime() | Current datetime | RETURN datetime() |
date() | Current date | RETURN date() |
time() | Current time | RETURN time() |
Null/Check Functions (3 functions)
| Function | What It Does | Example |
|---|---|---|
isEmpty(x) | Check if empty | RETURN isEmpty("") |
isNaN(x) | Check if not-a-number | RETURN isNaN(0/0) |
nullIf(v1, v2) | Return null if equal | RETURN nullIf(5, 5) |
Aggregation Functions (2 functions)
| Function | What It Does | Example |
|---|---|---|
count(x) | Count items | MATCH (n) RETURN count(n) |
length(path) | Path length | RETURN length(path) |
Utility Functions (2 functions)
| Function | What It Does | Example |
|---|---|---|
randomUUID() | Generate UUID | RETURN randomUUID() |
rand() | Random number 0-1 | RETURN rand() |
Real-World Example Collections
Example 1: Memory Search with Decay
// Find strong memories about a topic
MATCH (m:Memory)
WHERE m.content CONTAINS "database"
AND decayScore(m) > 0.6
RETURN m.title,
decayScore(m),
m.accessCount,
m.tier
ORDER BY decayScore(m) DESC
LIMIT 10Example 2: Data Cleaning
// Clean up user input
MATCH (user:User)
SET user.email = toLower(trim(user.email)),
user.name = trim(user.name)
WHERE user.email CONTAINS " " OR user.email <> toLower(user.email)
RETURN count(user) AS cleanedCountExample 2b: Identity Match Keys
Compare names and identifiers whatever their width, case, spacing or script of digits, in plain Cypher: NFKC, lower case (with the letters lower case leaves apart, such as ß, folded too), whitespace runs as one space, decimal digits as ASCII through a map the caller passes, and -./ dropped from a key of digits only.
// $digits maps each non-ASCII decimal digit to its ASCII digit, e.g. {`٢`: '2', `3`: '3', …}
WITH replace(replace(toLower(normalize($raw, NFKC)), 'ß', 'ss'), 'ς', 'σ') AS folded
WITH trim(string.regexReplace(reduce(out = '', c IN split(folded, '') | out + coalesce($digits[c], c)), '\s+', ' ')) AS k
RETURN CASE WHEN k =~ '[0-9./-]+' THEN string.regexReplace(k, '[-./]', '') ELSE k END AS key
// " MÜLLER Straße 1" → "müller strasse 1"; "١٢٣-٤٥٦/٧٨" → "12345678"Example 3: Calculate Distances
// Find nearby locations using Pythagorean theorem
MATCH (loc1:Location), (loc2:Location)
WHERE id(loc1) < id(loc2)
WITH loc1, loc2,
sqrt(pow(loc1.x - loc2.x, 2) + pow(loc1.y - loc2.y, 2)) AS distance
WHERE distance < 10
RETURN loc1.name, loc2.name, round(distance * 100) / 100 AS distanceKm
ORDER BY distanceExample 4: Text Processing
// Parse and normalize tags
MATCH (post:Post)
WITH post,
[tag IN split(toLower(post.tagString), ",") | trim(tag)] AS cleanTags
SET post.tags = cleanTags
RETURN count(post) AS processedExample 5: Find Similar Memories (Vector Search)
// Find memories similar to a query embedding
MATCH (m:Memory)
WHERE m.embedding IS NOT NULL
WITH m, vector.similarity.cosine(m.embedding, $queryEmbedding) AS similarity
WHERE similarity > 0.8
RETURN m.content,
similarity,
decayScore(m),
similarity * decayScore(m) AS combinedScore
ORDER BY combinedScore DESC
LIMIT 5Example 6: Statistical Analysis
// Analyze decay score distribution by label
MATCH (m:KnowledgeFact)
WITH labels(m)[0] AS label,
count(m) AS total,
avg(decayScore(m)) AS avgScore,
min(decayScore(m)) AS minScore,
max(decayScore(m)) AS maxScore
RETURN label, total,
round(avgScore * 100) / 100,
round(minScore * 100) / 100,
round(maxScore * 100) / 100Example 7: Conditional Logic with Coalesce
// Handle missing data gracefully
MATCH (user:User)
RETURN user.name,
coalesce(user.email, user.phone, "No contact info") AS contact,
coalesce(user.age, 0) AS ageExample 8: Generate Sequences
// Create pagination links
RETURN [page IN range(1, 10) |
"https://example.com/page/" + toString(page)] AS pageLinksExample 9: Complex String Manipulation
// Format display names
MATCH (person:Person)
WITH person,
split(person.fullName, " ") AS nameParts
RETURN person.fullName,
left(nameParts[0], 1) + ". " + last(nameParts) AS shortName,
toUpper(left(nameParts[0], 1) + left(last(nameParts), 1)) AS initialsExample 10: Trigonometry for Geo-coordinates
// Haversine formula for Earth distance
MATCH (p1:Place), (p2:Place)
WITH p1, p2,
radians(p1.lat) AS lat1, radians(p1.lon) AS lon1,
radians(p2.lat) AS lat2, radians(p2.lon) AS lon2
WITH p1, p2,
haversin(lat2 - lat1) + cos(lat1) * cos(lat2) * haversin(lon2 - lon1) AS h
RETURN p1.name, p2.name,
2 * 6371 * asin(sqrt(h)) AS distanceKmExample 11: Real-Time News Sentiment → Stock Prediction (Kalman Filter)
An LLM watches the Associated Press news feed in real-time, scoring each headline's market sentiment (-1.0 to +1.0). The Kalman filter smooths these noisy signals to predict stock movements.
// Step 1: Create stock trackers with Kalman filtering
UNWIND ["AAPL", "MSFT", "GOOGL", "TSLA", "NVDA"] AS symbol
CREATE (s:Stock {
symbol: symbol,
kalmanState: kalman.velocity.init(), // Track trends
sentiment: 0.0,
momentum: 0.0
})
// Step 2: LLM processes AP news headline and scores sentiment
// headline: "Apple announces record iPhone sales in China"
// $symbol = "AAPL", $sentimentScore = 0.72
// Step 3: Process the sentiment score through Kalman filter
MATCH (s:Stock {symbol: $symbol})
WITH s, kalman.velocity.process($sentimentScore, s.kalmanState) AS result
SET s.kalmanState = result.state,
s.sentiment = result.value,
s.momentum = result.velocity,
s.lastUpdate = timestamp()
RETURN s.symbol,
round(result.value * 100) / 100 AS smoothedSentiment,
round(result.velocity * 100) / 100 AS sentimentTrend,
CASE
WHEN result.velocity > 0.1 THEN "📈 BULLISH"
WHEN result.velocity < -0.1 THEN "📉 BEARISH"
ELSE "➡️ NEUTRAL"
END AS signal
// Step 4: Predict sentiment 5 time-steps ahead for all stocks
MATCH (s:Stock)
WHERE s.kalmanState IS NOT NULL
RETURN s.symbol,
round(s.sentiment * 100) / 100 AS currentSentiment,
round(s.momentum * 100) / 100 AS trend,
round(kalman.velocity.predict(s.kalmanState, 5) * 100) / 100 AS predictedSentiment,
CASE
WHEN kalman.velocity.predict(s.kalmanState, 5) > s.sentiment + 0.15 THEN "🚀 BUY SIGNAL"
WHEN kalman.velocity.predict(s.kalmanState, 5) < s.sentiment - 0.15 THEN "⚠️ SELL SIGNAL"
ELSE "HOLD"
END AS recommendation
ORDER BY abs(s.momentum) DESC
// Step 5: Find stocks about to cross sentiment threshold
MATCH (s:Stock)
WITH s,
s.sentiment AS current,
kalman.velocity.predict(s.kalmanState, 3) AS predicted
WHERE current < 0.7 AND predicted >= 0.7 // About to go strongly bullish
RETURN s.symbol, current, predicted, "🎯 BREAKOUT CANDIDATE" AS alertExample 12: IoT Sensor Smoothing with Kalman
// Initialize temperature sensors with Kalman filtering
CREATE (s:Sensor {
id: "greenhouse-temp-1",
location: "Zone A",
kalmanState: kalman.init({measurementNoise: 50.0})
})
// Process incoming temperature reading and smooth it
MATCH (s:Sensor {id: $sensorId})
WITH s, kalman.process($rawTemperature, s.kalmanState, 25.0) AS result
SET s.kalmanState = result.state,
s.temperature = result.value,
s.lastReading = timestamp()
RETURN s.id,
$rawTemperature AS raw,
round(result.value * 10) / 10 AS smoothed
// Alert on predicted overheating (predict 10 readings ahead)
MATCH (s:Sensor)
WHERE kalman.predict(s.kalmanState, 10) > 35.0
RETURN s.id, s.location,
round(kalman.predict(s.kalmanState, 10) * 10) / 10 AS predictedTemp,
"⚠️ Predicted overheat in ~10 readings" AS alertExample 13: Adaptive Kalman for Volatile Time Series
// Use adaptive filter for crypto (high volatility) - auto-switches modes
CREATE (c:Crypto {
symbol: "BTC",
kalmanState: kalman.adaptive.init({
trendThreshold: 0.05, // Switch to velocity mode on 5% trend
hysteresis: 5 // Quick adaptation
})
})
// Process price data - filter auto-switches between smoothing and tracking
MATCH (c:Crypto {symbol: $symbol})
WITH c, kalman.adaptive.process($price, c.kalmanState) AS result
SET c.kalmanState = result.state,
c.price = result.value,
c.filterMode = result.mode
RETURN c.symbol,
round(result.value) AS filteredPrice,
result.mode AS currentMode,
CASE result.mode
WHEN "velocity" THEN "📊 Trending market - tracking momentum"
ELSE "📉 Stable market - smoothing noise"
END AS interpretationFunction Categories by Use Case
Data Inspection
id(),labels(),type(),keys(),properties()
Data Cleaning
trim(),toLower(),toUpper(),replace(),split()
Type Safety
toInteger(),toFloat(),toString(),toBoolean()
Analytics
count(),avg(),sum(),min(),max()
Math & Stats
abs(),ceil(),floor(),round(),sqrt(),pow()
Spatial/Geo
sin(),cos(),haversin(),atan2(),sqrt()(for distances)
AI/ML Features
vector.similarity.cosine(),vector.similarity.euclidean()
Signal Processing & Prediction
kalman.init(),kalman.process(),kalman.predict()kalman.velocity.init(),kalman.velocity.process(),kalman.velocity.predict()kalman.adaptive.init(),kalman.adaptive.process()
Memory Management
- Decay system functions (see Memory Decay System)
Performance Notes
Fast Functions (< 1μs)
id(),labels(),type()toString(),toInteger(),toFloat()toLower(),toUpper()
Medium Functions (1-10μs)
trim(),replace(),split()abs(),ceil(),floor(),round()
Slower Functions (> 10μs)
sin(),cos(),tan()and other trig functionssqrt(),exp(),log()vector.similarity.*()- depends on vector size
Tips for Performance
- Cache computed values instead of recalculating
- Use indexes for WHERE clauses before function calls
- Batch operations instead of per-node function calls
- Pre-compute expensive math when possible
Common Patterns
Pattern: Case-Insensitive Search
MATCH (n)
WHERE toLower(n.name) = toLower($searchTerm)
RETURN nPattern: Safe Property Access
MATCH (n)
RETURN coalesce(n.optionalProperty, "default value") AS propPattern: Parse CSV Data
MATCH (n:RawData)
WITH n, split(n.csvLine, ",") AS fields
CREATE (p:ParsedData {
field1: trim(fields[0]),
field2: toInteger(trim(fields[1])),
field3: toFloat(trim(fields[2]))
})Pattern: Calculate Age
MATCH (person:Person)
RETURN person.name,
floor((timestamp() - person.birthTimestamp) / (365.25 * 24 * 60 * 60 * 1000)) AS agePattern: Vector Similarity Search
MATCH (doc:Document)
WHERE doc.embedding IS NOT NULL
WITH doc, vector.similarity.cosine(doc.embedding, $queryVector) AS score
WHERE score > 0.75
RETURN doc.title, score
ORDER BY score DESC
LIMIT 10db.index.vector.queryNodes — disabled-database behaviour
When the procedure is called against a database whose db.nornic.search.vector.enabled setting is false (or whose global NORNICDB_SEARCH_VECTOR_ENABLED alternative is false, with the per-database override winning):
- The procedure returns zero rows — the same shape as a query against an empty index.
- A
WARN-level log line is emitted withsubsystem=vector_searchand theindex_name:db.index.vector.queryNodes called against vector-disabled database — returning empty result - The Cypher query as a whole does not error — composite queries that gracefully handle empty vector results continue to succeed. This makes the procedure safe to call from query plans that may target either vector-enabled or vector-disabled databases.
To switch behaviour, flip the master switch via:
curl -X PUT http://localhost:7474/admin/databases/<db>/config \
-H "Content-Type: application/json" \
-d '{"overrides": {"db.nornic.search.vector.enabled": "true"}}'See Per-Database Search Index Flags.
References & Further Reading
These sources describe general concepts and Neo4j. NornicDB behavior can differ; use the descriptions above for NornicDB-specific details.
Memory Models
- Atkinson–Shiffrin model (1968) — three-store memory model.
- Ebbinghaus forgetting curve — exponential memory decay.
- Spaced repetition — review timing and retention.
Mathematical Functions
- Khan Academy — trigonometry basics.
- 3Blue1Brown — visual math explanations.
- Essence of Calculus — understanding exponentials and logarithms.
Vector Similarity
- Cosine similarity.
- Euclidean distance and cosine similarity — choosing a similarity measure.
Neo4j Cypher Reference
Documentation Status: Complete
Functions Documented: 62/62 (100%)
Examples Provided: 160+
Last Updated: November 29, 2025