AEL functions and terminals
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Reference page: part of the AEL reference. Covers functions with no collection data type (CDT)-typed receiver, and the terminals that end a path. See Applies to on the overview page for SDK and Database version requirements.
Record metadata functions
All forms are invoked on $ with ().
$.ttl() < 3600 /* expires in < 1 hour */$.recordSize() > 1024 /* large records */$.timeSinceLastUpdate() < 7200000 /* updated in last 2 hours */$.isTombstone() /* deleted records */$.setName() == 'critical'$.digestModulo(3) == 0 /* partition sampling */| Function | Returns | Description |
|---|---|---|
$.ttl() | INT | Remaining time-to-live in seconds |
$.voidTime() | INT | Absolute expiry time in nanoseconds (second resolution); -1 = never expires |
$.lastUpdateTime() | INT | Last update time in nanoseconds since Unix epoch (millisecond resolution) |
$.timeSinceLastUpdate() | INT | Time since last update in milliseconds |
$.setName() | STRING | Record’s set name |
$.key() | INT, STRING, or BLOB | Record primary key; optional :TYPE after () |
$.keyExists() | BOOL | Whether user key is stored |
$.isTombstone() | BOOL | Whether record is deleted |
$.recordSize() | INT | Total record size in bytes (introduced Database v7.0.0) |
$.deviceSize() | INT | Device size in bytes. Deprecated as of Database v8.1.0; use recordSize() instead |
$.memorySize() | INT | Memory size in bytes. Deprecated as of Database v8.1.0; use recordSize() instead |
$.digestModulo(n) | INT | Digest modulo n (unitless; n is a positive integer) |
Unlike path-level exists() (see Path read terminals), keyExists() and isTombstone() describe record metadata that is always resolvable. They return plain BOOL rather than TRILEAN and never evaluate to unknown.
In a read, isTombstone() is always false, because a read of a tombstone finds no record. It’s meaningful in Cross Datacenter Replication (XDR) filter expressions and in expressions a write request evaluates, where it’s true if the record was a tombstone.
Chaining a method off a metadata call requires parentheses around the metadata call: ($.ttl()).toString() works, but $.ttl().toString() is a parse error. See Parenthesised expressions.
voidTime() and lastUpdateTime() return nanosecond-scale integers with
coarser actual precision (second and millisecond granularity, respectively).
timeSinceLastUpdate() returns plain milliseconds.
type() applies only to a bare bin path, meaning $.bin itself rather than a nested path into its contents: $.bin.type(). There is no record-level $.type() on $ alone. exists() is not limited to bare bins — it’s also a general path read terminal usable after any navigation, for example $.profile.email.exists() to test a nested map key.
Standalone functions
Functions with no path receiver (single-argument calls use one positional argument unless noted):
| Function | Parameters | Return | Description |
|---|---|---|---|
abs(x) | numeric | same as x | Absolute value |
ceil(x) / floor(x) | FLOAT | FLOAT | Ceiling / floor |
min(a, b, …) / max(a, b, …) | numeric varargs | same type | Minimum / maximum |
countOneBits(x) | INT | INT | Population count |
findBitLeft(x:, value:) / findBitRight(x:, value:) | INT, TRILEAN | INT | Scan for bit value scanning left/right. value: — true = find a set bit, false = find a clear bit |
log(value:, base:) / pow(base:, exponent:) | FLOAT | FLOAT | Logarithm / power (named parameters) |
exclusive(a, b, …) | TRILEAN (varargs) | TRILEAN | Exactly one operand true; see Logical operators |
ceil($.price) /* round up */floor($.price) /* round down */min($.a:INT, $.b, $.c) /* smallest of three bins */countOneBits($.flags) /* number of set bits */findBitLeft(x: $.flags, value: true) /* index of the leftmost set bit */findBitRight(x: $.flags, value: false) /* index of the rightmost clear bit */log(value: 128.0, base: 2.0) /* 7.0 */pow(base: 2.0, exponent: 10.0) /* 1024.0 */GeoJSON
| Function | Parameters | Return | Description |
|---|---|---|---|
geoJson('…') | STRING (JSON) | GEO | Constructs a GEO value from a GeoJSON string literal |
geoCompare(a, b) | GEO, GEO | TRILEAN | Bidirectional spatial containment: true if either value contains, or is contained within, the other. Positional |
geoJson’s argument must be a string literal at parse time, for example geoJson('{"type":"Point","coordinates":[-122.4,37.7]}'). Dynamic forms such as geoJson($.str) are not supported.
geoCompare($.loc, geoJson('{"type":"Point","coordinates":[-122.349,47.620]}'))geoCompare(geoJson('{"type":"AeroCircle","coordinates":[[-122.0,37.4],3000.0]}'), $.loc)Bins typed as GEO are recognized automatically inside geoCompare(...). Use with a GEO2DSPHERE secondary index on the bin. In Python, write GeoJSON bins with set_to_geo_json(...). The Java Developer SDK’s setToGeoJson(...) is equivalent. For example, .bin("geo").setToGeoJson("{\"type\":\"Point\",\"coordinates\":[-122.4194, 37.7749]}"). See Update records for more information about updating records.
Path read terminals
There is no generic get() function in AEL. End a path after navigation/selectors/iteration with a named terminal to pick an explicit result shape, for example $.mapBin.{@a,b}.getKeyValues() or $.listBin.[0:3].count(). To pin a type instead, use the :TYPE suffix on the path (see Types and type suffixes), for example $.binName:INT. If no terminal is written, implicit get returns matched values (multi-select → flat LIST).
| Terminal | Return | Description |
|---|---|---|
| (implicit get) | scalar or LIST | Default: values at path |
getKeys() | LIST | Keys of matched elements (multi-select required) |
getKeyValues() | LIST | Flat [k,v,k,v,…] — not a MAP |
getMaps() | MAP | Key → value map (key-ordered by default) |
getTree() | MAP | Structure-preserving tree |
getIndexes() | INT or LIST | Index(es) of matched elements |
getRanks() | INT or LIST | Rank(s) of matched elements |
count() | INT | Element count on a single-select LIST/MAP path; match count on multi-select |
exists() | TRILEAN | Whether path/value exists |
toInt() / toFloat() | numeric | Cast path result (STRING or FLOAT → INT; STRING or INT → FLOAT) |
type() | INT | Runtime particle-type code (see particle types) — bare bin only ($.bin.type()) |
There is no separate getValues() terminal: the implicit get (no terminal written) already returns matched values, so a dedicated values-only terminal would be redundant.
Restrictions:
getKeys()/getKeyValues()on a bare single-key navigation without multi-select context is a parse error.getIndexes()/getRanks()/getMaps()are not valid on wildcard, filter, or inner-multi-select paths (deferred), for example$.m.*.x.getRanks().getMaps()requires a leaf map range or list selector; a list-only selector has no keys to return as a map (parse error).type()applies to$.binonly, not nested paths ($.bin.seg.type()is a parse error).exists()accepts both a bare bin ($.bin.exists()) and a nested path ($.bin.seg.exists()).toInt()/toFloat()require the receiver type to be known at parse time. If the bin is not already pinned elsewhere in the expression, attach:INT,:FLOAT, or:STRINGon the path before the call, for example$.bin:STRING.toInt() > 12.
Result shapes (multi-select):
| Terminal | Shape |
|---|---|
| Implicit get | Flat list of values |
getKeyValues() | Flat list of alternating keys and values |
getMaps() | Single map (key → value) |
getTree() | Nested map preserving path structure |
Path write terminals
Return the modified collection unless noted. Selectors {…} / […] attach to the path before the terminal, for example $.m.{@k}.remove(), not $.m.remove({@k}).
Map writes
| Function | Description |
|---|---|
setTo(value) | Upsert key from path navigation |
update(value) | Update only — fail if key missing |
insert(value) | Create only — fail if key exists |
add(amount) | Numeric delta on map value |
putItems(items) | Bulk upsert from MAP — mirrors setTo |
insertItems(items) | Bulk create-only from MAP — mirrors insert; fails if any key exists |
updateItems(items) | Bulk update-only from MAP — mirrors update; fails if any key is missing |
remove() | Remove matched entries |
clear() | Clear entire map |
$.m:MAP.putItems({a: 1, b: 2}) /* upsert both keys */$.m:MAP.insertItems({a: 1, b: 2}) /* fails if 'a' or 'b' already exists */$.m:MAP.updateItems({a: 1, b: 2}) /* fails if 'a' or 'b' is missing */putItems(), insertItems(), and updateItems() also accept the :NO_FAIL and :PARTIAL postfix flags to tolerate per-key failures instead of failing the whole call; see Postfix flags.
List writes
| Function | Description |
|---|---|
append(value) / appendItems(items) | Append element(s) |
insert(value) / insertItems(items) | Insert at index from path |
setTo(value) | Overwrite at index |
add(amount) | Increment at index |
remove() / clear() | Remove matched elements / clear list |
sort() | Sort list; optional :DROP_DUPS postfix |
List write terminals also accept :ADD_UNIQUE and :NO_FAIL where applicable; see Postfix flags.
Bulk symmetry: map putItems / insertItems / updateItems mirror single-key setTo / insert / update. List appendItems / insertItems mirror append / insert. List setTo / add at a path index mirror map single-key setTo / add (lists have no map-style update).
Path addressing (maps vs. lists): write verbs contain what is being operated on, and the path preceeding the verb contains where it goes. Maps are keyed: the path names one key (or the whole map for bulk); bulk keys and values live in the map argument. Lists are indexed: insert, insertItems, setTo, and add take the index from path navigation (for example $.l.[i].…); the argument holds value(s) only. The index is never a function parameter.
| Address in path | Payload in () | |
|---|---|---|
| Map single-key | key (for example $.m.k.…) | value / amount |
| Map bulk | whole map ($.m.…) | map of keys → values |
| List at index | index (for example $.l.[i].…) | value / list of values |
| List bulk append | whole list ($.l.…) | list of values |
insertItems overload: same verb, different path shape. $.m.insertItems({…}) is whole-map bulk create (no index leaf); $.l.[0].insertItems([…]) is positional bulk insert at the path index, analogous to $.l.[0].insert(value). appendItems is the list bulk op at container scope (append at end; no index leaf), parallel to map bulk ops on $.m.….
Name disambiguation: append(value) on a LIST receiver appends a list element. String concatenation uses the + operator, not a string method — see Arithmetic.
Path modify and remove
| Function | Description |
|---|---|
modify(expr) | Transform each matched element using @; result replaces element |
remove() | Delete matched elements; no-op if none match |
Create-order suffixes: modify() and remove() never accept create-order flags (see Collection create-order suffixes). For absent-path tolerance on those terminals, use :NO_FAIL.
Selector placement: {…} / […] selectors attach to the path before the terminal, for example $.m.{@k}.remove(), not $.m.remove({@k}). Terminal-argument selector forms are not part of AEL; dynamic selection in selectors waits for path-parameter (expr) support (see Parenthesised expressions).
Next steps
- String, BLOB, and HLL functions — method-style functions on typed receivers
- Control structures and postfix flags —
:NO_FAIL,:PARTIAL, and more - Operators — comparison, logical, and arithmetic operators