Operator Reference
The complete catalog of BlazeRules condition operators, grouped by family, with copy-pasteable YAML for each.
Each leaf condition pairs a field or set of fields with an op and its arguments. The operators below are grouped by data and execution semantics. Every snippet is valid inside a rule's conditions tree; see Rule DSL for the complete document structure.
Where these come fromAll 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 selects SIMD kernels (NEON, AVX2, or AVX-512) or scalar implementations at runtime. Scalar operator families produce the same bitmasks but remain bounded by per-row work, such as regex matching or haversine distance.
NEON-accelerated vs scalarVectorized: 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
| Family | Operators | Arg key |
|---|---|---|
| Numeric comparison | gt lt gte lte eq neq | value |
| Range | between_including between_excluding | value: [lo, hi] |
| Set membership | in not_in | values |
| Null / empty | is_null is_not_null is_empty is_not_empty | — |
| Cross-field | gt_field lt_field gte_field lte_field eq_field neq_field | other_field |
| Array / set | contains_any contains_all intersects not_intersects | values |
| Array length | array_len_gt array_len_lt array_len_eq | value |
| Bitfield flags | flags_any flags_all flags_none | mask |
| String | contains starts_with ends_with ci_eq | value |
| String length | length_gt length_lt length_eq | value |
| Network (CIDR) | ip_in_subnet ip_not_in_subnet | value (CIDR) |
| Temporal | before after within_last day_of_week_in time_of_day_between | value / values |
| Geo distance | distance_gt distance_lt | *_field + value (km) |
| Regex (RE2) | regex not_regex | value |
| Lookup (CSV) | in_lookup not_in_lookup | lookup |
The catalog contains 50 condition operators. Rules can also use windows, arithmetic expressions, vector distance, and ML model scores, which are linked at the end of this reference.
Important operator details
gt_field,lt_field,gte_field, andlte_fieldare for numeric fields.eq_fieldandneq_fieldalso work for string, categorical, and entity equality.- String and regex operators require
STRINGfields.regexandnot_regexuse RE2 partial matching;^...$provides whole-field matching. model_score.featuresandvector_distance.dimsmust be numeric fields.vector_distanceuses one scalar field per dimension, not one array column. Formetric: cosine,op: gtmeans "more similar."day_of_week_inuses0..6, where0is Sunday and6is Saturday.ip_in_subnet,ip_not_in_subnet, andipv4_cidr_setlookups are IPv4-only. IP fields may be dotted strings or numeric IPv4 values.is_emptyandis_not_emptyare text-like checks. Closed-enum array operators use the bitset path when enum values are declared in YAML.
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 and is_not_null work on any field. is_empty and is_not_empty are text-like checks for STRING, CATEGORICAL, or ENTITY_KEY fields. 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. Ordering comparisons (gt_field, lt_field, gte_field, lte_field) are for numeric fields. Equality comparisons (eq_field, neq_field) work for numeric fields and for string/categorical/entity equality.
- {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]}array_len_gt array_len_lt array_len_eq test the number of elements.
- {field: tags, op: array_len_gt, value: 0}
- {field: tags, op: array_len_lt, value: 10}
- {field: tags, op: array_len_eq, value: 2}flags_any flags_all flags_none test bits of an integer field against a mask.
- {field: signal_flags, op: flags_any, mask: 1}
- {field: signal_flags, op: flags_all, mask: 3}
- {field: signal_flags, op: flags_none, mask: 8}
Closed-enum arrays are vectorizedWhen an array field is a closed enum (its allowed
valuesare declared infields:), BlazeRules encodes it as an integer bitset and runscontains_*/intersectson the bitset path. Keep closed-enum array sets at 63 values or fewer for that representation. 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). These operators require STRING fields.
- {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_regexrun on RE2 per row and use partial matching. Anchors such as^...$provide whole-field matching. RE2 avoids catastrophic backtracking, but cost still scales with rows examined. Place cheaper predicates first in anandto reduce the candidate set.
Network (CIDR)
ip_in_subnet / ip_not_in_subnet test an IPv4 field against a CIDR block. The field may be a dotted IPv4 string or a numeric IPv4 value stored in INT32 / INT64. IPv6 is not supported by these operators.
- {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 and compares against the engine's current wall clock; day_of_week_in takes 0..6 where 0 is Sunday and 6 is Saturday; time_of_day_between takes an [from_hour, to_hour] list and may wrap across midnight.
- {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]}
- {field: event_ts_ms, op: time_of_day_between, value: [0, 23]}Geo distance
distance_gt / distance_lt compare the distance between two lat/lon points against a threshold in kilometers. These use four numeric field keys rather than a single field. The implementation uses a fast equirectangular path for short distances and a haversine fallback for larger distances.
- 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: 5000Lookups (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.
Per-entity velocity over a time window: count sum avg ratio min max.
model_score evaluates an ONNX model over numeric feature fields and compares its output.
vector_distance uses one numeric field per vector dimension with cosine / l2 / dot.
How matched rules become actions, scores, and risk bands.
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.8Windows, briefly (full detail in Windows):
- window:
entity_field: card_token
function: count
duration_seconds: 3600
op: gt
value: 3Updated about 2 months ago