Query Syntax
  • 04 Mar 2026
  • 5 Minutes to read
  • Contributors
  • Dark
    Light

Query Syntax

  • Dark
    Light

Article summary

Darwinium has it's Query Syntax used for:

  • Searching Data in Investigations
  • Defining signals in rules

The query syntax was designed to be portable - meaning that in most occasions it can be interchanged between a query in the Investigations view and a condition in the rules editor.

Quick Start

// Simple search
event_type = 'misc_other'

// Most attribute have dots in their name, based on their attribute group
profiling.javascript.os= "Mac OS X"
profiling.javascript.browser= "Firefox"

// Some attributes have CONTEXTs, accessed with [' ']
identity['ACCOUNT'].email['PERSONAL'].email = 'test@test.com'
outcome['CHAMPION'].decision_strategy.result = 'reject'

// Can combine logic; AND, OR, (brackets).
// Logic can be UPPER or lower. Attributes are lower only.
event_type = 'misc_other' OR step_name = 'Login'

// IN can be used to check many values in a list. 
// Single or double quotes work for strings.
event_type IN ('account_login_success', "account_login_failed")

// Logical negative is done with NOT or ! character
step_url != "/login"
step_url NOT IN ("/login", "/register")

// Empty attribute values are checked with null keyword
step_url = null
step_url != null
// Empty string attributes can also be searched with
step_url = ''

// Mathematical operators work on numerical attributes
payment.amount >= 10

// Maps eg. feature:value dicts can be accessed with attr['keyvalue']
// Note: This is true of attribute CONTEXTs too.
outcome['CHAMPION'].features.general['cnt_dvcid_for_eml_inc'] != null
outcome['CHAMPION'].features.general['cnt_dvcid_for_eml_inc'] > 2

// Presence in an Array eg. signals can be checked with has function
// Functions are camelCase
has(outcome['CHAMPION'].models.signals, "Device used first time")
!has(outcome['CHAMPION'].models.signals, "Device used first time")

Data Type Considerations

Data TypeDescription
String LiteralContain within quotes eg. journey_name = 'marketplace'. Absent data can be searched with: = ""
MapsUse square brackets and quotes to access values for certain keys eg. custom.general_purpose['valid'] = 'yes'
Arrays
  • use an index to reference the exact value. e.g previous_steps[0] = 'MyLogin'
  • use has to check for the presence of a value in an array. eg has(previous_steps, 'MyLogin')

Query Operators

All operators are case insensitive

OperatorBehaviorExample
<, >, <=, >=Mathematical comparison on numeric data, returning booleantime_since_last_step > 10000
= , !=Equality and Inequality operators, returning boolean. Inequality includes empty data.previous_step != 'HomePage'
(will return events where step is named something else INCLUDING where empty)
+ (add), - (minus), * (multiply), / (divide), % (modulo)Mathematical operators on numeric data, returning numeric.time_since_last_step > 10000 * 60
( , )Brackets either for expression evaluation priority or to define lists of values(transaction.amount+1)/100 > 1
TRUE, FALSEBoolean literals
NULLExpression for checking NULL.
Note: Should instead use empty string "" for absent data in string types.
AND, ORLogical operators to combine boolean expressions. Returns boolean.step_method = 'post' AND event_type = 'PreAuthentication'
IN, NOTCheck if attribute value is in or not in a list of possibilities. Concise way of multiple equality checks linked with or. Can also be used to match a value with wildcard contexts. Returns boolean.
  • step_name not in ('ChangeDetails', 'ChangeDetailsPage')
  • 'foo@bar.com' in identity['*'].email['*'].email
ASCasts a value of one type to another type. datetime casts date to T00:00:00+00:00
  • 'true' as boolean
  • 3.14 as string = "3.14"
  • '3.14' as number > 3
  • timestamp as int
  • (timestamp - (identity['ACCOUNT'].date_of_birth AS datetime)) < 20 years

Logic & String Functions

OperatorBehaviorExample
has(arrayAttribute, value)Checks if value is present in the arrayAttribute. Returns boolean; true if value is present, false otherwise.has(previous_steps, 'ChangeDetails')
if(condition, valueIfTrue, valueIfFalse)Inline If. Condition is any boolean expression. Returns type given in valueIfTrue or valueIfFalse.if(previous_step = 'LoginAttempt', 1, 0)
regexMatch(attribute, regexString)Check if an attribute matches a regex pattern. Returns boolean. Note - this will not work in the query editor for PII attributes (but will in rules and features)regexMatch(auction.title, '.*fluff'
concat(...values)Concatenates multiple strings into a single stringconcat("hello", "world") = "helloworld"
modelScore(modelName)Shorthand for outcome[CHAMPION].models.score["*.modelName"] where * means matching any stepmodelScore("bot") < -800

Date Functions

OperatorBehaviorExample
now()Returns a date containing the current timestamp in milliseconds since epoch, January 1, 1970timestamp < now()
day(dateAttribute)Returns the day of monthday(timestamp) = 6
month(dateAttribute)Returns the month of a year for the input datemonth(timestamp) = 2
year(dateAttribute)Returns the year of an input date or timestampyear(timestamp) = 2024
dayOfWeek(timestamp)Returns integer of day of week in UTC, 1=Monday, 7=SundaydayOfWeek(timestamp)=1
duration_s / duration_ms / duration_us Convert a number of to an intervalduration_ms(outcome['CHAMPION'].features.general['tmsncfrs_eml']) < 24 hours
seconds / minutes / hours / days / months / years Compare a time intervalduration_ms(outcome['CHAMPION'].features.general['tmsncfrs_eml']) < 24 hours

Math Functions

OperatorBehaviorExample
random()Returns a random number between 0 and 1
floor(x)Takes as input a real number x, and gives as output the greatest integer less than or equal to xfloor(2.35) = 2
ceil(x)computes the smallest integer that is greater than or equal to xceil(2.35) = 3
log(x)Log natural of xlog(1) = 0
log2(x)log2 of xlog2(16) = 4
log10(x)log10 of xlog10(100) = 2
abs(x)absolute value of x
  • abs(-1) = 1
  • abs(1) = 1
sqrt(x)square root of xsqrt(4) = 2
cos(x)cosine of x
sin(x)sine of x
tan(x)tangent of x
acos(x)arc-cosine of x
asin(x)arc-sine of x
atan(x)arc-tan of x
cosh(x)hyperbolic cosine of x
sinh(x)hyperbolic sine of x
tanh(x)hyperbolic tangent of x
acosh(x)arc-hyperbolic cosine of x
asinh(x)arc-hyperbolic sine of x
atanh(x)arc-hyperbolic tangent of x

Geographic Functions

OperatorBehaviorExample
distance(to, from, unit)Calculates the distance between 2 coordinate pairs, with units 'miles' or 'kilometers'distance([profiling.tcp_connection['PRIMARY'].ipinfo.latitude, profiling.tcp_connection['PRIMARY'].ipinfo.longitude] , [profiling.tcp_connection['DNS'].ipinfo.latitude, profiling.tcp_connection['DNS'].ipinfo.longitude] , "kilometers") > 1000

Contexts

You may notice in Attribute Reference that a number of attributes have contexts. For example:

identity['ACCOUNT'].email['PERSONAL'].email

in this case, identity[] has the following possible CONTEXTS:

  • ACCOUNT
  • BENEFICIARY
  • BILLING
  • ORIGINATOR

..and email[] has the following possible CONTEXTS:

  • PERSONAL
  • WORK

These contexts help to namespace attribute values such that you can store information on multiple accounts, for example - a Primary account (identity['ACCOUNT']) and a beneficiary (identity['BENEFICIARY']) at the same time, in the same event. This is inherently useful for developing rules around these specific contexts, as is the case with multi-party payments, for example.

You may also use wildcards for contexts

identity['ACCOUNT'].email['*'].email

Was this article helpful?

Changing your password will log you out immediately. Use the new password to log back in.
First name must have atleast 2 characters. Numbers and special characters are not allowed.
Last name must have atleast 1 characters. Numbers and special characters are not allowed.
Enter a valid email
Enter a valid password
Your profile has been successfully updated.
ESC

Eddy AI, facilitating knowledge discovery through conversational intelligence