Understanding functions
Goal
By the end of this guide you should be able to identify, use, and compose DataPrime functions to transform and evaluate values within your datasets.
Why it matters
Functions in DataPrime are the precision tools of your queries. They let you inspect individual fields within your logs, calculate values, validate formats, work with timestamps, manipulate arrays, and more—all inline, at the field level. If commands define what to do with documents, functions define how to compute new values or check conditions.
Mastering functions allows you to:
- Clean and normalize messy fields
- Build rich conditional logic
- Perform math and string operations without leaving the platform
- Get the most out of filtering, aggregating, and alerting
What are functions?
Functions are expressions that take one or more inputs and return a value. That value can be:
- stored in a new field (via
create
), - used in a condition (e.g.
filter length(name) > 10
), - or passed into another function (function chaining).
Functions are available in two interchangeable notations:
- Function notation:
length(name)
- Method notation:
name.length()
These two notations are equivalent. Use whichever is more readable and useful in context.
Common function categories
Functions are grouped into categories based on what kind of data they operate on. Here’s a breakdown of the most common ones. See the language reference for a list of all functions.
String functions
Transform or evaluate strings—essential for log cleanup and normalization.
length(str)
– Number of characters.contains(str, substr)
– Checks if a string contains a value.startsWith()
,endsWith()
– Prefix/suffix matching.pad()
,toLowerCase()
,trim()
– Modify string content.
Number functions
Work with and calculate numerical values.
abs()
,floor()
,ceil()
– Basic math.mod()
,round()
,power()
– Advanced operations.log()
,log2()
– Work with logarithms.max()
,min()
– Compare multiple values.fromBase()
,toBase()
– Convert between number bases.
Time functions
Parse, format, and compute with timestamps and intervals.
now()
– The current timestamp.parseTimestamp()
,formatTimestamp()
– Work with time strings.diffTime()
– Time between two timestamps.addTime()
,subtractTime()
– Adjust timestamps.parseInterval()
,formatInterval()
– Work with time durations.
Array functions
Manipulate and search within arrays.
arrayLength(arr)
– Count elements.arrayContains(arr, value)
– Check membership.arrayJoin(arr, delimiter)
– Flatten to string.arrayAppend()
,arrayRemove()
,arrayInsertAt()
– Modify contents.arraySplit()
– Turn a string into an array.
Validation & utility functions
Check or generate structured values.
isUuid()
,randomUuid()
– Work with UUIDs.ipInSubnet()
,ipPrefix()
– Work with IPs.decodeBase64()
,encodeBase64()
– Encode/decode safely.matches()
– Test a regex match.
Control flow functions
Allow inline conditional logic and fallback values.
if(condition, then, else)
– Simple branching.firstNonNull()
– Return the first non-null value.case
,case_equals
,case_contains
– Complex branching logic.
Function composition and chaining
Functions can be nested and/or chained. For example:
This is equivalent to:
Both are valid. Use the style that’s most readable and appropriate for your use case.
Expected output
Most functions return simple types: string
, number
, boolean
, timestamp
, array
, etc.
These can then be:
- displayed in the document
- used in
filter
,groupby
,create
, etc. - passed into other functions
Example
Let’s say we want to normalize a user email and tag whether it's an internal account:
source logs
| create email_lower from email.toLowerCase()
| create user_is_internal from email_lower.contains('@company.com')
| choose email, email_lower, user_is_internal
If the original document looked like this:
Then the output will look like:
This shows how two chained functions can be used in combination—toLowerCase()
and contains()
—and their outputs visualized using choose
.
Gotchas and best practices
- Watch out for nulls: Many functions will return
null
if passed a null input. - Don’t over-nest: For deeply nested expressions, consider breaking them into multiple
create
steps. - Use casting when needed: Use
:number
or:string
to convert types, e.g.duration:number
. - Use method notation for clarity: Especially when chaining multiple operations on a field.