AEL string, BLOB, and HLL functions
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Reference page: part of the AEL reference. Covers method-style functions on STRING, BLOB, and HLL receivers. See Applies to on the overview page for SDK and Database version requirements.
String path functions
Method-style on a STRING receiver may be a bin root ($.str.…), a nested or pathed string value ($.m.x.…), or a chained string result. Positions and lengths are Unicode code points.
toInt() and toFloat() share names with path read terminals. On bins whose type is not already resolved, pin :STRING before the call, for example $.code:STRING.toInt(), so the compiler selects string parsing rather than a numeric cast.
Read and transform
| Function | Return | Description |
|---|---|---|
strlen() | INT | Character count |
substr(from: [, to:]) | STRING | Substring; from inclusive; to exclusive if present; negative indices count from end; invalid range → empty string |
charAt(index:) | STRING | Single Unicode codepoint at index; index clamped to [0, length]; past end → empty string |
upper() / lower() / caseFold() / normalizeNFC() | STRING | Case and Unicode NFC normalization |
trim() / trimStart() / trimEnd() | STRING | Trim Unicode whitespace at both ends / leading / trailing |
find(needle:, occurrence:) | INT | Position of nth occurrence; -1 if not found; occurrence 0 → error; occurrence -1 selects the last match; treats precomposed and decomposed Unicode forms as equal |
contains(needle:) | TRILEAN | Substring test; same canonical-equivalence rules as find() |
padStart(length:, pad:) / padEnd(length:, pad:) | STRING | Pad to minimum length; pad string may be multi-character |
toInt() / toFloat() | numeric | Parse numeric string |
regexReplace(pattern:, replace:) | STRING | Perl-compatible regex replace; replaces the first match by default, or every match when pattern: carries the g (global) flag. pattern: must be a regex literal, not a quoted string. $n in replace: references capture groups |
startsWith(prefix) / endsWith(suffix) | TRILEAN | Prefix / suffix test |
split(separator) | LIST | Split to list of strings |
repeat(count) | STRING | Repeat string |
isUpper() / isLower() | TRILEAN | All characters uppercase / lowercase |
isNumeric() | TRILEAN | Numeric string test |
bytesLength() | INT | Length in bytes (as opposed to strlen()’s codepoint count) |
toBlob() | BLOB | String to blob |
b64Decode() | BLOB | Base64 string to blob; fails on invalid base64 |
/* Replace only the first run of digits with '#' (default: first match only): */$.sku.regexReplace(pattern: /[0-9]+/, replace: '#')
/* Replace every run of digits with '#' (g flag opts in to global replace): */$.sku.regexReplace(pattern: /[0-9]+/g, replace: '#')
/* Case-insensitive whole-word match, redacting the first match: */$.logLine.regexReplace(pattern: /\berror\b/i, replace: '[REDACTED]')
/* Reformat 'Last, First' to 'First Last' using capture groups: */$.name.regexReplace(pattern: /^(\w+),\s*(\w+)$/, replace: '$2 $1')Regex literals
/pattern/ or /pattern/flags, using Perl-compatible regex syntax. Flags compose by concatenation, for example /pat/im. A regex literal must appear directly in the expression: it cannot come from a bin or variable.
| Flag | Meaning | Valid on |
|---|---|---|
i | Case-insensitive (Unicode case folding) | =~ and regexReplace() |
m | ^ and $ match line boundaries | =~ and regexReplace() |
s | Dot matches newlines | =~ and regexReplace() |
g | Global: replace every match instead of only the first | regexReplace() only |
Only i, m, s, and g are supported. g is valid only on regexReplace() — using it with =~ is a parse error.
Modify (return new string)
| Function | Return | Description |
|---|---|---|
splice(offset:, value:) | STRING | Insert at offset; named splice (not insert) to avoid collision with list/map insert(); offset clamped to [0, length] — past end appends, for example splice(offset: 4, value: "and") on "yes" → "yesand" |
overwrite(offset:, value:) | STRING | Overwrite at offset; offset past end → error (not suppressed by :NO_FAIL) |
snip(from: [, to:]) | STRING | Remove range; from >= to → unchanged |
replace(find:, replace:) | STRING | First occurrence; treats precomposed and decomposed Unicode forms as equal |
replaceAll(find:, replace:) | STRING | All occurrences; same canonical-equivalence rules as replace() |
$.msg.splice(offset: 0, value: '[URGENT] ')$.path.snip(from: 5)$.m.x.upper():NO_FAIL /* :NO_FAIL applies to absent path only */$.m.x.overwrite(offset: 12, value: '-patched-'):NO_FAIL /* :NO_FAIL applies to absent path only; offset past end still errors */$.m.x.splice(offset: 12, value: '-patched-'):NO_FAIL /* tolerant offset (clamp/append); insert, not overwrite */Cross-type string conversions
| Function | Receiver type | Return | Description |
|---|---|---|---|
toString() | INT, FLOAT, BOOL, STRING, BLOB | STRING | Format as string; STRING is identity; BLOB must be valid UTF-8 |
On a bin path, pin or infer the receiver type before calling, for example $.amount:INT.toString(). Record metadata uses the parenthesis rule, for example ($.recordSize()).toString(), not $.recordSize().toString().
List string function
CDT list operation that joins list elements into one string:
| Function | Return | Description |
|---|---|---|
$.list.join(separator) | STRING | Join list elements with separator |
Chaining
String methods that return STRING may chain left-to-right ($.email.trim().lower()). A method that returns INT or TRILEAN ends the string-method chain — no further .stringMethod() may follow it. Use that result in a comparison, arithmetic, or other surrounding expression instead.
/* Valid: each call returns STRING */$.sku.trim().upper().replace(find: '-', replace: '_')
/* Parse error: find() returns INT; .replace() cannot follow */$.sku.find(needle: '-', occurrence: 1).replace(find: '_', replace: '.')
/* Valid: INT result used in an expression, not chained to another string method */$.sku.find(needle: '-', occurrence: 1) == 3$.email.strlen() > 0BLOB (bit) path functions
Method-style on a BLOB receiver. Offsets and sizes are in bits unless noted as byte offset.
Read
| Function | Return | Description |
|---|---|---|
bitGet(offset:, size:) | BLOB | Extract bit range |
b64Encode() | STRING | Base64-encode the blob |
bitCount(offset:, size:) | INT | Count set bits in range |
bitLscan(offset:, size:, value:) / bitRscan(offset:, size:, value:) | INT | Scan left/right for bit value |
bitGetInt(offset:, size: [, signed:]) | INT | Extract as integer; signed default false |
Modify (return modified BLOB)
| Function | Return | Description |
|---|---|---|
bitResize(byteSize:) | BLOB | Resize to byte length |
bitInsert(byteOffset:, value:) / bitRemove(byteOffset:, byteSize:) | BLOB | Insert / remove bytes |
bitSet(offset:, size:, value:) / bitOr(…) / bitXor(…) / bitAnd(…) / bitNot(offset:, size:) | BLOB | Bitwise ops on range |
bitLshift(offset:, size:, shift:) / bitRshift(offset:, size:, shift:) | BLOB | Shift range |
bitAdd(offset:, size:, value: [, signed:]) / bitSubtract(…) | BLOB | Add / subtract in range; overflow fails |
bitSetInt(offset:, size:, value:) | BLOB | Write integer in range |
Write-policy postfix flags: bit modify ops accept :CREATE_ONLY, :UPDATE_ONLY, :NO_FAIL, and :PARTIAL where listed in the following table. These flags control whether the bin may be created or updated, not individual bit ranges within an existing blob. Bit read ops (preceding section) reject all write-policy flags.
:CREATE_ONLY and :UPDATE_ONLY are mutually exclusive. :PARTIAL on BLOB bit ops does not imply :NO_FAIL; it means clip the operation to the end of the blob and apply it (see the flag table in Postfix flags). Combine :NO_FAIL with :CREATE_ONLY or :UPDATE_ONLY when a conflict should be ignored, for example bitResize(byteSize: 4):CREATE_ONLY:NO_FAIL. Combine :PARTIAL and :NO_FAIL explicitly when both clip tolerance and ignored flag conflicts are needed.
Valid flags by op — flags not listed for an op are invalid:
| Op | :CREATE_ONLY | :UPDATE_ONLY | :NO_FAIL | :PARTIAL |
|---|---|---|---|---|
bitResize | ✓ | ✓ | ✓ | — |
bitInsert | ✓ | ✓ | ✓ | — |
bitRemove | — | ✓ | ✓ | ✓ |
bitSet, bitOr, bitXor, bitAnd, bitNot | — | ✓ | ✓ | ✓ |
bitLshift, bitRshift | — | ✓ | ✓ | ✓ |
bitAdd, bitSubtract, bitSetInt | — | ✓ | ✓ | — |
Only bitResize and bitInsert can create a missing bin; :CREATE_ONLY applies only to those two. All other modify ops require an existing blob unless :NO_FAIL suppresses the error (:PARTIAL alone does not).
$.header.bitResize(byteSize: 4):CREATE_ONLY /* create bin only if absent */$.header.bitInsert(byteOffset: 0, value: x'01'):UPDATE_ONLY$.header.bitSet(offset: 8, size: 8, value: x'01'):UPDATE_ONLY:NO_FAIL$.header.bitRemove(byteOffset: 0, byteSize: 2):PARTIALInteger bitwise operators (&, |, ^, ~, <<, >>, >>>) apply to whole 64-bit INT values, not BLOB bit ranges. See Integer bitwise.
HLL path functions
HLL read path functions operate on bins typed as HLL. They mirror the server HyperLogLog read operations and the HLL expressions reference (hll_get_count, hll_get_union_count, and so on). Use them in where(...) filters and other Boolean AEL contexts.
The receiver path ($.h in the following tables) is the HLL bin the function runs against.
Read functions
| Function | Parameters | Returns | Description |
|---|---|---|---|
$.h.hllCount() | — | INT | Estimated number of unique entries in the sketch. Uses the cached count; see refresh_count on the underlying HLL type if the bin was modified since the last count. |
$.h.hllDescribe() | — | LIST | Two-element list [index_bit_count, min_hash_bit_count] describing the sketch precision. |
$.h.hllMayContain(list) | LIST of values to check | INT (1 or 0) | Returns 1 if the sketch may contain all listed elements (probabilistic membership test), otherwise 0. |
$.h.hllUnion(peer) | HLL bin path (single peer) | HLL | HLL value that is the union of the receiver bin and peer. |
$.h.hllUnionCount(peer) | HLL bin path (single peer) | INT | Estimated cardinality of the union of the receiver bin and peer. |
$.h.hllIntersectCount(peer) | HLL bin path (single peer) | INT | Estimated cardinality of the intersection of the receiver bin and peer. The underlying feature allows more than two HLLs to participate when minhash bits are enabled. That isn’t reachable from AEL today, because only one peer bin path can be passed per call. |
$.h.hllSimilarity(peer) | HLL bin path (single peer) | FLOAT | Estimated Jaccard similarity between the receiver bin and peer (typically 0.0–1.0). Same single-peer limitation as hllIntersectCount. |
For hllUnion, hllUnionCount, hllIntersectCount, and hllSimilarity, the argument is a single peer HLL bin path, such as $.cohort_a, not a list. AEL collection literals are static only, so an explicit list like [$.cohort_a, $.cohort_b] is a parse error. There is no AEL syntax for combining three or more peer sketches in one call. To combine three or more peers, use the HLL expressions Exp builder directly, which accepts a list of peer HLLs.
$.h.hllCount() > 1000000$.h.hllDescribe() == [14, 0]$.h.hllMayContain(['alice', 'bob']) == 1$.h.hllUnionCount($.cohort_a) > 50000$.h.hllIntersectCount($.cohort_a) > 100$.h.hllSimilarity($.cohort_a) >= 0.8$.h.hllUnion($.cohort_a) == $.cohort_bCompare estimated counts and similarities against thresholds in filters (for example high-cardinality segments or overlapping audiences). For modify-then-read composition with server expressions, see the HLL expressions reference.
Modify
The Developer SDK does not support write-side HLL in AEL filters. In Python, initialize and update sketches with the builder API instead (hll_init, hll_add on WriteBinBuilder, both requiring a bin-direct receiver, not a nested path into an HLL value); see Update records. The Java Developer SDK’s fluent builder has no hllInit/hllAdd equivalent in this release — use the classic client’s non-fluent HLLOperation.init() / HLLOperation.add() static factories instead. The grammar defines these modify functions for completeness with other AEL-based tools such as Aerospike Voyager:
| Function | Parameters | Returns | Description |
|---|---|---|---|
$.h.hllInit(indexBits: [, minHashBits:]) | INT [, INT] | HLL | Create or reset the sketch with the given index (and optional minhash) bit counts. |
$.h.hllAdd(list [, indexBits: [, minHashBits:]]) | LIST [, INT [, INT]] | HLL | Add the list elements to the sketch. Optional indexBits / minHashBits create the bin if it does not exist. |
Create vs. update control (HLL): hllInit accepts :CREATE_ONLY, :UPDATE_ONLY, and :NO_FAIL. hllAdd accepts :CREATE_ONLY and :NO_FAIL only — :UPDATE_ONLY is a parse error on hllAdd. BLOB bit modify ops use the same flag names with per-op scope (see Valid flags by op earlier in this page). Map and list paths express create-only and update-only through verbs: single-key insert(value) / update(value) and bulk insertItems(items) / updateItems(items) (see Path write terminals).
| Flag | hllInit | hllAdd | Effect |
|---|---|---|---|
| (default) | ✓ | ✓ | Upsert — create, re-init, or add as appropriate |
:CREATE_ONLY | ✓ | ✓ | Fail if the operation would modify an existing bin |
:UPDATE_ONLY | ✓ | — | Fail if the operation would create a new bin; parse error on hllAdd |
:NO_FAIL | ✓ | ✓ | On a create/update conflict, succeed as a no-op instead of failing |
:CREATE_ONLY and :UPDATE_ONLY are mutually exclusive. Combine with :NO_FAIL when a conflict should be ignored, for example hllInit(indexBits: 12):CREATE_ONLY:NO_FAIL.
$.visitors.hllInit(indexBits: 12):CREATE_ONLY /* init only if bin absent */$.visitors.hllInit(indexBits: 12):UPDATE_ONLY /* re-init only if bin exists */$.visitors.hllAdd(['u1', 'u2']):CREATE_ONLY /* add only when creating the bin */$.visitors.hllAdd(['u1']):NO_FAIL /* tolerate missing bin / type mismatch */Next steps
- Control structures and postfix flags — the full postfix flag semantics
- Functions and terminals — record metadata and path terminals
- Operators — comparison, logical, and arithmetic operators