Operator Reference

The complete catalog of BlazeRules condition operators, grouped by family, with copy-pasteable YAML for each.

This page catalogs every condition operator BlazeRules supports. Each leaf condition pairs a field (or fields) with an op and its arguments. Operators are grouped into families below; every snippet is valid inside a rule's conditions tree (see Rule DSL).

📘

Where these come from

All examples are drawn from the project's canonical rules.yaml, which exercises every operator family in one file. If in doubt, that file is the source of truth for syntax.

How conditions are written

A leaf condition is a small map. The argument key depends on the operator:

  • value — a single scalar (or a 2-element list for ranges/between).
  • values — a list, for set/array membership.
  • other_field — another column, for cross-field comparisons.
  • mask — an integer bitmask, for bitfield flags.
  • lookup — a named lookup set, for lookup membership.
  • Geo operators take lat_field / lon_field / other_lat_field / other_lon_field.
conditions:
  and:
    - {field: amount, op: gt, value: 1000}
    - {field: country_code, op: in, values: [US, GB]}

Vectorization

BlazeRules runs predicate families either on SIMD (NEON / AVX2 / AVX-512) kernels or on correct scalar code, selected at runtime. Scalar families still produce the same bitmask — they are just bounded by per-row work (e.g. regex, haversine).

📘

NEON-accelerated vs scalar

Vectorized: numeric, range, set membership, null/empty, bitfield, and closed-enum array bitset checks.
Scalar (correct, cost ∝ rows examined): cross-field, string, regex, IP/CIDR, temporal, geo, and lookup.

Operator catalog at a glance

FamilyOperatorsArg key
Numeric comparisongt lt gte lte eq neqvalue
Rangebetween_including between_excludingvalue: [lo, hi]
Set membershipin not_invalues
Null / emptyis_null is_not_null is_empty is_not_empty
Cross-fieldgt_field lt_field gte_field lte_field eq_field neq_fieldother_field
Array / setcontains_any contains_all intersects not_intersectsvalues
Array lengtharray_len_gt array_len_lt array_len_eqvalue
Bitfield flagsflags_any flags_all flags_nonemask
Stringcontains starts_with ends_with ci_eqvalue
String lengthlength_gt length_lt length_eqvalue
Network (CIDR)ip_in_subnet ip_not_in_subnetvalue (CIDR)
Temporalbefore after within_last day_of_week_in time_of_day_betweenvalue / values
Geo (haversine)distance_gt distance_lt*_field + value (km)
Regex (RE2)regex not_regexvalue
Lookup (CSV)in_lookup not_in_lookuplookup

That is 50 operators in total. Beyond them, rules can also use windows, arithmetic expressions, vector distance, and ML model scores — covered at the end of this page with links to their dedicated guides.


Numeric comparison

gt lt gte lte eq neq — compare a numeric field against a constant.

- {field: amount, op: lt, value: 10000}
- {field: account_age_days, op: gte, value: 0}
- {field: account_age_days, op: lte, value: 3650}
- {field: merchant_bin, op: eq, value: 411111}
- {field: amount, op: neq, value: 13}

Range

between_including (inclusive bounds) and between_excluding (exclusive bounds). value is a two-element [low, high] list.

- {field: hour_of_day, op: between_including, value: [0, 23]}
- {field: amount, op: between_excluding, value: [1, 99999]}

Set membership

in / not_in test a categorical/entity field against a list.

- {field: country_code, op: in, values: [US, GB, IN]}
- {field: device_type, op: not_in, values: [bot]}

Null and empty

is_null is_not_null is_empty is_not_empty take no argument. is_empty matches null or zero-length; is_null matches only a missing value.

- {field: optional_note, op: is_null}
- {field: description, op: is_not_null}
- {field: optional_note, op: is_empty}
- {field: description, op: is_not_empty}

Cross-field comparison

gt_field lt_field gte_field lte_field eq_field neq_field compare two columns of the same record using other_field.

- {field: amount, op: gt_field, other_field: amount_limit}
- {field: amount, op: gte_field, other_field: fee}
- {field: fee, op: lt_field, other_field: amount}
- {field: billing_country, op: eq_field, other_field: shipping_country}
- {field: billing_country, op: neq_field, other_field: ip_country}

Arrays and flags

contains_any contains_all intersects not_intersects test an array field against a set of values.

- {field: tags, op: contains_any, values: [vip, risky]}
- {field: tags, op: contains_all, values: [vip, trusted]}
- {field: tags, op: intersects, values: [trusted, risky]}
- {field: tags, op: not_intersects, values: [chargeback]}
📘

Closed-enum arrays are vectorized

When an array field is a closed enum (its allowed values are declared in fields:), BlazeRules encodes it as an integer bitset and runs contains_* / intersects on the NEON bitset path. Open-ended arrays fall back to scalar.

Strings and regex

contains starts_with ends_with ci_eq (case-insensitive equals), length_gt length_lt length_eq, and regex / not_regex (RE2 syntax).

- {field: description, op: contains, value: payment}
- {field: description, op: starts_with, value: card}
- {field: description, op: ends_with, value: approved}
- {field: user_agent, op: ci_eq, value: "Mozilla/5.0"}
- {field: description, op: length_gt, value: 5}
- {field: description, op: length_lt, value: 200}
- {field: device_fingerprint, op: length_eq, value: 10}
- {field: description, op: regex, value: "card.*payment"}
- {field: user_agent, op: not_regex, value: "bot|crawler"}
🚧

Regex cost

regex / not_regex run on RE2 per row. They are correct and safe (no catastrophic backtracking) but cost scales with rows examined — put cheaper predicates first in an and so they prune the set.

Network (CIDR)

ip_in_subnet / ip_not_in_subnet test an IP string against a CIDR block.

- {field: ip_address, op: ip_in_subnet, value: "10.0.0.0/8"}
- {field: ip_address, op: ip_not_in_subnet, value: "192.168.0.0/16"}

Temporal

Operate on a millisecond timestamp field. before / after take an epoch-ms value; within_last takes a number of seconds; day_of_week_in takes a list (1–7); time_of_day_between takes an [from_hour, to_hour] list.

- {field: event_ts_ms, op: before, value: 4102444800000}
- {field: event_ts_ms, op: after, value: 1704067200000}
- {field: event_ts_ms, op: within_last, value: 315360000}
- {field: event_ts_ms, op: day_of_week_in, values: [1, 2, 3, 4, 5, 6, 7]}
- {field: event_ts_ms, op: time_of_day_between, value: [0, 23]}

Geo (haversine)

distance_gt / distance_lt compare the great-circle distance between two lat/lon points against a threshold (kilometers). These use four field keys rather than a single field.

- op: distance_gt
  lat_field: billing_lat
  lon_field: billing_lon
  other_lat_field: shipping_lat
  other_lon_field: shipping_lon
  value: 10
- op: distance_lt
  lat_field: billing_lat
  lon_field: billing_lon
  other_lat_field: shipping_lat
  other_lon_field: shipping_lon
  value: 5000

Lookups (CSV-backed)

in_lookup / not_in_lookup test a field against a named lookup set declared in the top-level lookups: block. See Lookups.

- {field: merchant_id, op: in_lookup, lookup: blocked_merchants}
- {field: country_code, op: not_in_lookup, lookup: blocked_countries}
- {field: merchant_bin, op: in_lookup, lookup: risky_bins}
- {field: ip_address, op: in_lookup, lookup: vpn_ranges}

Beyond simple operators

These rule constructs are computed once per batch as derived columns, then compared with an ordinary numeric operator. Each has a dedicated guide.

Arithmetic expressions let a comparison run over a computed value (add sub mul div, nestable):

- op: gt
  expr:
    op: div
    left: amount
    right: available_credit
  value: 0.8

Windows, briefly (full detail in Windows):

- window:
    entity_field: card_token
    function: count
    duration_seconds: 3600
    op: gt
    value: 3