Real-time signal filtering and prediction for time series data. Perfect for smoothing noisy sensor readings, tracking market sentiment, or predicting trends.
// Find strong memories about a topicMATCH(m:Memory)WHEREm.contentCONTAINS"database"ANDdecayScore(m)>0.6RETURNm.title,decayScore(m),m.accessCount,m.tierORDERBYdecayScore(m)DESCLIMIT10
// Clean up user inputMATCH(user:User)SETuser.email=toLower(trim(user.email)),user.name=trim(user.name)WHEREuser.emailCONTAINS" "ORuser.email<>toLower(user.email)RETURNcount(user)AScleanedCount
// Parse and normalize tagsMATCH(post:Post)WITHpost,[tagINsplit(toLower(post.tagString),",")|trim(tag)]AScleanTagsSETpost.tags=cleanTagsRETURNcount(post)ASprocessed
// Find memories similar to a query embeddingMATCH(m:Memory)WHEREm.embeddingISNOTNULLWITHm,vector.similarity.cosine(m.embedding,$queryEmbedding)ASsimilarityWHEREsimilarity>0.8RETURNm.content,similarity,decayScore(m),similarity*decayScore(m)AScombinedScoreORDERBYcombinedScoreDESCLIMIT5
// Analyze decay score distribution by labelMATCH(m:KnowledgeFact)WITHlabels(m)[0]ASlabel,count(m)AStotal,avg(decayScore(m))ASavgScore,min(decayScore(m))ASminScore,max(decayScore(m))ASmaxScoreRETURNlabel,total,round(avgScore*100)/100,round(minScore*100)/100,round(maxScore*100)/100
// Haversine formula for Earth distanceMATCH(p1:Place),(p2:Place)WITHp1,p2,radians(p1.lat)ASlat1,radians(p1.lon)ASlon1,radians(p2.lat)ASlat2,radians(p2.lon)ASlon2WITHp1,p2,haversin(lat2-lat1)+cos(lat1)*cos(lat2)*haversin(lon2-lon1)AShRETURNp1.name,p2.name,2*6371*asin(sqrt(h))ASdistanceKm
Example 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 filteringUNWIND["AAPL","MSFT","GOOGL","TSLA","NVDA"]ASsymbolCREATE(s:Stock{symbol:symbol,kalmanState:kalman.velocity.init(),// Track trendssentiment: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 filterMATCH(s:Stock{symbol:$symbol})WITHs,kalman.velocity.process($sentimentScore,s.kalmanState)ASresultSETs.kalmanState=result.state,s.sentiment=result.value,s.momentum=result.velocity,s.lastUpdate=timestamp()RETURNs.symbol,round(result.value*100)/100ASsmoothedSentiment,round(result.velocity*100)/100ASsentimentTrend,CASEWHENresult.velocity>0.1THEN"๐ BULLISH"WHENresult.velocity<-0.1THEN"๐ BEARISH"ELSE"โก๏ธ NEUTRAL"ENDASsignal// Step 4: Predict sentiment 5 time-steps ahead for all stocksMATCH(s:Stock)WHEREs.kalmanStateISNOTNULLRETURNs.symbol,round(s.sentiment*100)/100AScurrentSentiment,round(s.momentum*100)/100AStrend,round(kalman.velocity.predict(s.kalmanState,5)*100)/100ASpredictedSentiment,CASEWHENkalman.velocity.predict(s.kalmanState,5)>s.sentiment+0.15THEN"๐ BUY SIGNAL"WHENkalman.velocity.predict(s.kalmanState,5)<s.sentiment-0.15THEN"โ ๏ธ SELL SIGNAL"ELSE"HOLD"ENDASrecommendationORDERBYabs(s.momentum)DESC// Step 5: Find stocks about to cross sentiment thresholdMATCH(s:Stock)WITHs,s.sentimentAScurrent,kalman.velocity.predict(s.kalmanState,3)ASpredictedWHEREcurrent<0.7ANDpredicted>=0.7// About to go strongly bullishRETURNs.symbol,current,predicted,"๐ฏ BREAKOUT CANDIDATE"ASalert
// Initialize temperature sensors with Kalman filteringCREATE(s:Sensor{id:"greenhouse-temp-1",location:"Zone A",kalmanState:kalman.init({measurementNoise:50.0})})// Process incoming temperature reading and smooth itMATCH(s:Sensor{id:$sensorId})WITHs,kalman.process($rawTemperature,s.kalmanState,25.0)ASresultSETs.kalmanState=result.state,s.temperature=result.value,s.lastReading=timestamp()RETURNs.id,$rawTemperatureASraw,round(result.value*10)/10ASsmoothed// Alert on predicted overheating (predict 10 readings ahead)MATCH(s:Sensor)WHEREkalman.predict(s.kalmanState,10)>35.0RETURNs.id,s.location,round(kalman.predict(s.kalmanState,10)*10)/10ASpredictedTemp,"โ ๏ธ Predicted overheat in ~10 readings"ASalert
Example 13: Adaptive Kalman for Volatile Time Series¶
// Use adaptive filter for crypto (high volatility) - auto-switches modesCREATE(c:Crypto{symbol:"BTC",kalmanState:kalman.adaptive.init({trendThreshold:0.05,// Switch to velocity mode on 5% trendhysteresis:5// Quick adaptation})})// Process price data - filter auto-switches between smoothing and trackingMATCH(c:Crypto{symbol:$symbol})WITHc,kalman.adaptive.process($price,c.kalmanState)ASresultSETc.kalmanState=result.state,c.price=result.value,c.filterMode=result.modeRETURNc.symbol,round(result.value)ASfilteredPrice,result.modeAScurrentMode,CASEresult.modeWHEN"velocity"THEN"๐ Trending market - tracking momentum"ELSE"๐ Stable market - smoothing noise"ENDASinterpretation
When the procedure is called against a database whose NORNICDB_SEARCH_VECTOR_ENABLED is false (per-DB or global, with the per-DB override winning):
The procedure returns zero rows โ the same shape as a query against an empty index.
A WARN-level log line is emitted with subsystem=vector_search and the index_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.