Cypher Functions & Procedures

Built-in functions, threat-intel procedures, schema introspection, and other features beyond core Cypher syntax.

Updated May 2026cypher Integration

Cypher Functions & Procedures Documentation

Functions, stored procedures, and built-in features. For the underlying Cypher syntax see Cypher Syntax. The full list of threat-intel feed sources lives in the Feed Catalog.

Function reference

Aggregation

FunctionDescriptionExample
count(*)Count rowsMATCH (n:TLD) RETURN count(*)
count(DISTINCT x)Count unique valuesMATCH (n:COUNTRY) RETURN count(DISTINCT n.name)
collect(x)Collect values into a listMATCH (n:RIR) RETURN collect(n.name)
sum(x)Sum numeric valuesUNWIND [1,2,3] AS x RETURN sum(x)
avg(x)AverageUNWIND [1,2,3] AS x RETURN avg(x)
min(x)MinimumUNWIND [3,1,4] AS x RETURN min(x)
max(x)MaximumUNWIND [3,1,4] AS x RETURN max(x)
stdev(x)Sample standard deviationUNWIND [1,2,3,4,5] AS x RETURN stdev(x)
stdevp(x)Population standard deviationUNWIND [1,2,3,4,5] AS x RETURN stdevp(x)
percentileDisc(x, p)Discrete percentileUNWIND [1,2,3,4,5] AS x RETURN percentileDisc(x, 0.5)
percentileCont(x, p)Continuous percentileUNWIND [1,2,3,4,5] AS x RETURN percentileCont(x, 0.9)

Note: min() and max() work on both aggregated rows and list literals.

String

FunctionExampleResult
toUpper("hello")"HELLO"
toLower("HELLO")"hello"
trim(" hello ")"hello"
lTrim(" hello")"hello"
rTrim("hello ")"hello"
replace("hello world", "world", "cypher")"hello cypher"
substring("hello world", 6)"world"
substring("hello world", 0, 5)"hello"
split("a.b.c", ".")["a", "b", "c"]
left("hello", 3)"hel"
right("hello", 3)"llo"
reverse("hello")"olleh"
size("hello")5

Numeric

FunctionExampleResult
abs(-42)42
ceil(3.14)4.0
floor(3.99)3.0
round(3.5)4
sign(-42)-1
rand()Random float 0..1
log(e())1.0
log10(100)2.0
exp(1)2.718...
sqrt(144)12.0
e()2.718...
pi()3.14159...

Arithmetic operators: +, -, *, /, %, ^ (exponent), + (string concatenation).

Trigonometric

sin(), cos(), tan(), asin(), acos(), atan(), atan2(), degrees(), radians()

All accept and return radians, except degrees() which converts radians to degrees, and radians() which converts degrees to radians.

Geospatial

FunctionDescription
point({latitude: 37.77, longitude: -122.42})Create a geographic point
point.distance(p1, p2)Haversine distance in meters between two points

Collection

FunctionExampleResult
head([1,2,3])1
last([1,2,3])3
tail([1,2,3])[2,3]
size([1,2,3])3
reverse([1,2,3])[3,2,1]
range(1, 5)[1,2,3,4,5]
range(0, 10, 2)[0,2,4,6,8,10]
keys({a: 1, b: 2})["a", "b"]

List predicates

FunctionExampleResult
all(x IN list WHERE pred)all(x IN [2,4,6] WHERE x % 2 = 0)true
any(x IN list WHERE pred)any(x IN [1,2,3] WHERE x > 2)true
none(x IN list WHERE pred)none(x IN [1,2,3] WHERE x > 5)true
single(x IN list WHERE pred)single(x IN [1,2,3] WHERE x = 2)true
reduce(acc=init, x IN list | expr)reduce(t=0, x IN [1,2,3,4,5] | t+x)15

Node and relationship

FunctionDescription
labels(n)Returns the list of labels on a node, e.g. ["HOSTNAME"]
type(r)Returns edge type name, e.g. "RESOLVES_TO"
id(n)Returns node ID
properties(n)Returns all properties as a map
startNode(r)Source node of a relationship
endNode(r)Target node of a relationship
nodes(p)All nodes in a path
relationships(p)All relationships in a path
length(p)Number of edges in a path

Type conversion

FunctionExampleResult
toString(42)"42"
toInteger("42")42
toFloat("3.14")3.14
toBoolean("true")true
toIntegerList(["1","2"])[1, 2]
toFloatList(["1.1","2.2"])[1.1, 2.2]
toStringList([1,2])["1", "2"]
toBooleanList(["true","false"])[true, false]
isEmpty("")true
coalesce(null, null, 42)42
randomUUID()UUID string

Date and time

FunctionDescription
datetime()Current UTC datetime
date()Current date
timestamp()Current epoch milliseconds
datetime("2024-01-15T10:30:00Z")Parse an ISO 8601 datetime string
duration("P1Y2M3D")Create a duration from ISO 8601
duration.between(dt1, dt2)Duration between two datetimes

Property access on datetime values: .year, .month, .day, .hour, .minute, .second, .epochMillis, .epochSeconds.


Features

Threat intelligence

WhisperGraph indexes 40+ threat intelligence feeds across 18 categories. This data comes from whisper-feeds, a companion service that aggregates live threat feed data from public and commercial sources, with hourly incremental and daily full refresh cycles.

The threat intelligence layer works like this:

  • IPs and hostnames that appear in threat feeds are connected to FEED_SOURCE nodes via LISTED_IN virtual edges.
  • Each FEED_SOURCE belongs to one or more CATEGORYs (e.g., "C2 Servers", "Phishing", "General Blacklists").
  • ASN nodes may carry threat properties like maxThreatScore and overallThreatLevel.
  • The explain() procedure computes a composite score that factors in feed count, feed weights, recency, and network density.

Querying threat feeds directly:

MATCH (ip:IPV4 {name: "185.220.101.1"})-[:LISTED_IN]->(f:FEED_SOURCE)
RETURN ip.name, f.name
[
  {"ip.name": "185.220.101.1", "f.name": "Dan Tor Exit"},
  {"ip.name": "185.220.101.1", "f.name": "FireHOL Level 2"},
  {"ip.name": "185.220.101.1", "f.name": "Spamhaus DROP"}
]

Scored threat assessment with explain():

explain() accepts IPs, domains, ASNs, and CIDR ranges.

CALL explain("185.220.101.1")
[{
  "indicator": "185.220.101.1",
  "type": "ip",
  "found": true,
  "score": 5.28,
  "level": "INFO",
  "explanation": "185.220.101.1 is listed in 3 threat feed(s). Score 5.3 (Informational - minimal risk).",
  "factors": [
    "Listed in 3 source(s) with combined weight 2.20",
    "Base score: 2.20 x log2(3 + 1) = 4.40",
    "Recency boost: x1.2 (last seen just now)"
  ]
}]
CALL explain("cloudflare.com")
[{
  "indicator": "cloudflare.com",
  "type": "domain",
  "found": true,
  "score": 0.0,
  "level": "NONE",
  "explanation": "Not listed in any threat intelligence feed"
}]
CALL explain("AS60729")
[{
  "indicator": "AS60729",
  "type": "asn",
  "found": true,
  "score": 0.0,
  "level": "NONE",
  "explanation": "AS60729 (TORSERVERS-NET, DE) has a reputation score of 48.5 (Suspicious)."
}]
CALL explain("185.220.101.0/24")
[{
  "indicator": "185.220.101.0/24",
  "type": "network",
  "found": true,
  "score": 0.0,
  "level": "MEDIUM",
  "explanation": "Network 185.220.101.0/24 contains 167 listed IPs across multiple threat feeds."
}]

The level field returns one of: NONE, INFO, LOW, MEDIUM, HIGH, CRITICAL.

Feed sources (all 40):

FeedCategory
AlienVault ReputationReputation
Binary Defense BanlistGeneral Blacklists
Blocklist.de AllGeneral Blacklists
Blocklist.de MailSpam
Blocklist.de SSHBrute Force
Botvrij DomainsMalicious Domains
Botvrij Dst IPsC2 Servers
Brute Force BlockerBrute Force
C2 Intel 30dC2 Servers
C2 TrackerC2 Servers
CERT.pl DomainsMalicious Domains
CINS ScoreGeneral Blacklists
Cloudflare Radar Top 1MPopularity/Trust
DNS RD AbuseGeneral Blacklists
Dan Tor ExitTOR Network
ET Compromised IPsGeneral Blacklists
Feodo TrackerC2 Servers
FireHOL Abusers 1dGeneral Blacklists
FireHOL AnonymousProxies
FireHOL Level 1General Blacklists
FireHOL Level 2General Blacklists
FireHOL Level 3General Blacklists
FireHOL WebClientGeneral Blacklists
GreenSnow BlacklistGeneral Blacklists
Hagezi LightAd/Tracking Blocklists
Hagezi ProAd/Tracking Blocklists
IPsumGeneral Blacklists
InterServer RBLGeneral Blacklists
MalwareBazaar RecentMalware Distribution
OpenPhish FeedPhishing
SSH Client AttacksBrute Force
SSH Password AuthBrute Force
SSL IP BlacklistGeneral Blacklists
Spamhaus DROPGeneral Blacklists
Spamhaus EDROPGeneral Blacklists
StevenBlack HostsAd/Tracking Blocklists
ThreatFox IOCsC2 Servers
Tor Exit NodesTOR Network
Tranco Top 1MPopularity/Trust
URLhaus RecentMalware Distribution

Categories (all 18):

Ad/Tracking Blocklists, Anonymization Infrastructure, Attack Sources, Brute Force, C2 Servers, General Blacklists, Malicious Domains, Malicious Infrastructure, Malware Distribution, Phishing, Popularity/Trust, Proxies, Reference Data, Reputation, Spam, TOR Network, Threat Intelligence, VPNs.

Domain history

The whisper.history() procedure returns timestamped WHOIS and BGP snapshots for an indicator.

CALL whisper.history("cloudflare.com")
[
  {
    "indicator": "cloudflare.com",
    "type": "domain",
    "queryTime": "2024-06-13 18:31:16",
    "createDate": "2009-02-17",
    "updateDate": "2024-01-09",
    "expiryDate": "2033-02-17",
    "registrar": "CloudFlare, Inc.",
    "nameServers": "..."
  },
  {
    "indicator": "cloudflare.com",
    "type": "domain",
    "queryTime": "2020-05-01 07:03:56",
    "createDate": "2009-02-17",
    "registrar": "Cloudflare, Inc."
  }
]

Supported indicator types: domain, IP, ASN, CIDR, hash.

History works on registrable domains (e.g., google.com), not subdomains (www.google.com). Subdomains return empty results.

Quota and plan info

CALL whisper.quota()

Returns your current plan tier, hourly query limit, usage count, maximum traversal depth, and concurrent query count.

Schema introspection

Discover what is in the graph without knowing the schema up front.

-- All node labels with counts
CALL db.labels()

Returns every label in the graph with its count, including virtual labels (REGISTERED_PREFIX, ANNOUNCED_PREFIX, FEED_SOURCE, CATEGORY).

-- All edge types with counts
CALL db.relationshipTypes()

Returns every edge type with its count, including virtual edge types (LISTED_IN, ANNOUNCED_BY, OPERATES).

-- All property keys
CALL db.propertyKeys()

Returns all known property keys in the graph.

-- Full schema summary
CALL db.schema()

Returns labels, relationship types, and property keys in a single response.

These are all instant lookups, regardless of graph size.