Overview
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Reference page: canonical Aerospike Expression Language (AEL) lexical rules, literals, and type system, for filter and operation expressions.
Applies to
- Aerospike Developer SDKs (Java 21+ and Python 3.10+)
- Aerospike Database 8.2.0 or later. This applies to both filter APIs with
.where(...)and operation-expression APIs:selectFrom,upsertFrom,insertFrom,updateFrom.
AEL text is parsed and compiled entirely on the server — there is no
client-side AEL parser in the shipping SDKs. (An ANTLR grammar,
Condition.g4, exists in both SDK repos, but it is not part of the
branches these SDKs ship from; it does not run for .where(), selectFrom,
upsertFrom, insertFrom, or updateFrom.) That server-side AEL compiler
is what the 8.2.0 requirement gates.
Audience
Application developers authoring AEL text (Intermediate).
Prerequisites
- A connected
session - AEL overview or equivalent filter-expression familiarity
Outcome
You can look up authoritative AEL syntax (lexical rules, literals, and types) and navigate to the rest of the AEL reference for paths, operators, functions, and control structures.
About AEL text
AEL is a text-based domain-specific language that compiles to Aerospike Database expressions. It is used for filter expressions (.where()) and as the source of read/write expressions in both Java and Python: .selectFrom() / .select_from(), .insertFrom() / .insert_from(), .updateFrom() / .update_from(), and .upsertFrom() / .upsert_from().
The same AEL text also works in Aerospike Voyager, so you can author and test an expression there, then copy it directly into application code.
For task-oriented examples of passing AEL text to SDK builders (filters on query, batch, and single-key commands; read and write operation expressions), see Author AEL expressions. That page also covers the evaluation model: the server parses and compiles AEL text on every call, and the SDKs support positional placeholders (?0, ?1, and so on) that are substituted into the AEL text on the client before it is sent.
When a filter returns nothing or a string fails to compile, see Debug AEL expressions.
In this reference
Overview (this page)
Lexical rules, literals, and the AEL type system, including TRILEAN and type suffixes.
Paths and navigation
Record and bin paths, quoted bin names, parenthesised expressions, wildcard iteration, and collection create-order suffixes.
Selectors and loop variables
Map selectors {…}, list selectors […], inverted selections, loop variables, and selector punctuation.
Operators
Comparison, in, regex match, logical operators and TRILEAN truth tables, arithmetic, integer bitwise, and precedence.
Functions and terminals
Record metadata functions, standalone functions, GeoJSON, and path read/write terminals.
String, BLOB, and HLL functions
Method-style functions on STRING, BLOB, and HLL receivers, including write-policy flags.
Control structures and postfix flags
when and let, plus the full postfix flag reference (:NO_FAIL, :PARTIAL, and more).
Type inference and limits
How AEL resolves types at parse time, compile limits, and name-collision disambiguation.
Lexical rules
- Whitespace (spaces, tabs, newlines) is ignored between tokens.
- Block comments only:
/* … */. Comments may appear wherever whitespace is allowed. Nested block comments are not allowed. - Unquoted identifiers match
[A-Za-z_][A-Za-z0-9_]*(bin path segments, function names,letvariable names). Variable names cannot be quoted. - Reserved words (lowercase):
and,or,not,in,let,then,when,default,unknown,error,true,false, andexclusive. These are language keywords only. Collection data type (CDT)/write verbs are not grammar keywords. They use their own identifiers (setTo,add,insertItems, and so on) instead of bare tokens likesetorincrement. A separate, narrower rule applies when a verb-like word is itself the name of a map key: see Quoted notation for map key names. - Language constants (UPPERCASE):
NIL,INF(CDT ordering sentinels in list/map literal comparisons);INT,FLOAT,STRING,BOOL,BLOB,LIST,MAP,GEO,HLL(type constants, also usable as :TYPE suffixes);VECTOR(reserved for future capabilities, not used yet);*(wildcard value inside list or map literals only). - Function and method arguments generally use
name: valuesyntax, for examplelog(value: 128, base: 2). For every function that uses named parameters, every argument must be labelled; labels may appear in any order. Exceptions:- Single-argument calls (
abs,ceil,floor,countOneBits,geoJson, and so on) take one positional argument, for exampleabs(-3). - Variable-argument calls of the same type (
min,max) are positional, for examplemin(3, 5, 7, 2). geoCompare(a, b)is positional, and both arguments areGEO.
- Single-argument calls (
Literals
| Form | Example | Notes |
|---|---|---|
| Integer | 21, 0xff, 0b1010 | Decimal with optional +/-; hex and binary supported |
| Float | 3.14, .5 | Decimal point required; 10. is invalid — use 10.0 |
| String | 'Tim', "O'Brien", 'line1\nline2' | Standard escape sequences are supported: see Escape sequences below |
| Boolean | true, false | |
| BLOB | x'cafe', X'ffee' | Even-length hex with x/X prefix |
| Base64 | b64'SGVsbG8=' | Invalid base64 is a parse error; b64'' is allowed |
| List | [1, 2, 3], [] | Optional :SORTED / :UNSORTED suffix after ]; unsorted is the default |
| Map | {a: 1, b: 2}, {} | Keys can be strings, integers, or BLOB; optional :UNORDERED after }; key-ordered is the default |
| Regex | /pattern/, /pat/im | Perl-compatible; flags i, m, s compose by concatenation; g (global replace) is valid only on regexReplace() |
Quoted strings apply everywhere quotes are allowed: expression literals, map keys, and quoted bin name segments on paths.
Escape sequences
AEL string literals support standard escape sequences:
| Escape | Meaning |
|---|---|
\\ | Backslash |
\n | Newline |
\t | Tab |
\r | Carriage return |
\"/\' | Quote, matching the enclosing style |
\0 | NUL |
\xHH | Byte with hex value HH |
\n/\r let a single-line source literal produce a multi-line string value: "line1\nline2" is valid. To include the enclosing quote character in a string, either escape it ('O\'Brien') or switch quote styles ("O'Brien") — both are valid.
A list literal without a suffix is unsorted. Without a suffix, a bin-level list bin is created UNSORTED on write, but a nested list that does not exist fails on access unless the path segment carries its own create-order suffix.
A map literal without a suffix is key-ordered — the same ordering as :KEY_ORDERED on a path segment. There is no :KEY_ORDERED literal suffix; key-ordered is the default. Key-value ordered maps (:KEY_VALUE_ORDERED) are not available in literal syntax; use a path create-order suffix when materializing that container on navigation.
:UNORDERED means three different things depending on where it appears, and each is independent of the others:
| Position | Controls |
|---|---|
{a: 1}:UNORDERED (map literal, see Literals) | The stored value’s ordering |
$.m:UNORDERED.k.setTo(1) (path create-order suffix, see Collection create-order suffixes) | Ordering when the path creates a missing map on navigation |
$.m.getMaps():UNORDERED (postfix flag, see Postfix flags) | Return shape of the read result only — does not change the stored map |
For regex literal flags and syntax, see Regex literals.
Types
Concrete types
| Type | Description |
|---|---|
INT | Integer |
FLOAT | Floating-point |
STRING | Unicode string (code points for string functions) |
BOOL | Boolean literal values — true and false only |
TRILEAN | Three-valued logic result — true, false, or unknown (see TRILEAN) |
BLOB | Byte array |
LIST | Ordered collection |
MAP | Key-value collection |
GEO | GeoJSON value |
HLL | HyperLogLog bin |
TRILEAN (three-valued logic)
Many predicates and logical combinations return TRILEAN, not plain BOOL. A TRILEAN result is one of:
| Value | Meaning |
|---|---|
true | Definitively yes |
false | Definitively no |
unknown | Indeterminate, typically because a referenced bin, key, or path operand is absent or cannot be evaluated |
unknown is not false. In filters, an unknown result usually causes the expression to fail for that record (the record is not selected). Whether an unknown result surfaces to the application as an error or simply excludes the record depends on application and API flags (for example filter vs. read mode and explain options), not on AEL syntax.
For the and / or / not truth tables, see Logical operators.
Reserved literals unknown and error (see Conditional: when) are separate value forms used in expressions such as when (…, default => unknown). They are not the same as a predicate returning unknown because a bin is missing.
Types and type suffixes
AEL is strongly typed, but types are inferred wherever possible, so an explicit
:TYPE suffix is only required when the type can’t be inferred from context.
For example:
$.bin == 'Steve'doesn’t require a type on$.binbecause it can be inferred from the comparison.$.a + $.b + $.c == $.d and $.b > 3.1doesn’t require types ona,b,c, ord:bmust be aFLOAT(from the comparison with3.1), soa,c, anddmust also beFLOATfrom the addition and equality.$.left == $.right:STRINGdoes need a type suffix because neither bin’s type can be inferred without one.
Attach :TYPE to pin static type on a path segment or loop variable:
| Form | Meaning |
|---|---|
$.bin:INT | Strict typing on bin. The rest of this AEL expression carries this type forward for that bin. |
$.bin:LOCAL:INT | Loose typing for this occurrence only — see Use of LOCAL below |
$.l.[0]:INT | Type the value read at that selector |
$.m.key:STRING | Type the value at a map key |
@:INT | Type loop variable @ in a filter or modify body |
@.price:FLOAT | Type a field read from @ |
$.key():INT | Optional return type on a no-arg record metadata function |
Valid type names: INT, FLOAT, STRING, BOOL, BLOB, LIST, MAP, GEO, HLL. These are type pins on any path operand: bin root ($.bin:INT), navigation tail ($.m.k:STRING), loop variable (@:FLOAT), and so on.
:MAP and :LIST are type pins only. They tell the compiler to treat a path value as a map or list (required on some reads, such as wildcard-first paths — see Wildcard iteration). They do not create containers and are not create-order flags. Missing bins are materialized by write verbs (putItems, setTo, and so on) or by collection create-order suffixes on path segments.
toInt() / toFloat() and type pins: the same method names are used for string parsing (see String path functions) and numeric casting (see Path read terminals). A call such as $.amount.toFloat() does not tell the compiler whether $.amount is numeric text to parse or an integer to cast. Pin the source type on the path before the call: $.amount:INT.toFloat() casts an integer, and $.amount:STRING.toFloat() parses a string. Literals and other already-typed receivers need no suffix ("1234".toInt()).
Casing: path suffix modifiers and postfix flags use UPPERCASE (:LOCAL:, :MAP, :KEY_ORDERED, :SORTED, :NO_FAIL, and so on).
Use of LOCAL
In some rare cases, a bin such as $.amount may hold different types across records, such as INT or FLOAT. AEL normally determines the type of a bin from its first use and keeps that type for the whole expression. For example, in $.b > 3 and $.a == $.b, $.b is inferred to be INT by the first comparison, and that inference carries forward to the second comparison.
:LOCAL types each occurrence for that branch only. It does not pin a single canonical type on the bin record-wide. In a when, every branch must produce the same result type. In this example, integer amounts are cast to FLOAT so the branches unify and can be divided by $.quantity for an average price:
when ( $.amount.type() == INT => $.amount:LOCAL:INT.toFloat(), default => $.amount:LOCAL:FLOAT) / $.quantity:INT.toFloat()Next steps
Paths and navigation
Record and bin paths, quoted bin names, and collection create-order suffixes.
Author AEL expressions
Filters, read projection, and write expressions on single-key, batch, and query commands.