---
title: "Overview"
description: "AEL reference overview: lexical rules, literals, and types for the Aerospike Expression Language, used by the Java and Python Developer SDKs."
---

# Overview

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/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`](https://aerospike.com/docs/develop/client/sdk/connect)
-   [AEL overview](https://aerospike.com/docs/develop/client/sdk/concepts/ael) 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](https://aerospike.com/download/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](https://aerospike.com/docs/develop/client/sdk/concepts/ael/authoring-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](https://aerospike.com/docs/develop/client/sdk/concepts/ael/debugging-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.

[Paths and navigation →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/paths)

Selectors and loop variables

Map selectors `{…}`, list selectors `[…]`, inverted selections, loop variables, and selector punctuation.

[Selectors and loop variables →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/selectors)

Operators

Comparison, `in`, regex match, logical operators and `TRILEAN` truth tables, arithmetic, integer bitwise, and precedence.

[Operators →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/operators)

Functions and terminals

Record metadata functions, standalone functions, GeoJSON, and path read/write terminals.

[Functions and terminals →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/functions)

String, BLOB, and HLL functions

Method-style functions on `STRING`, `BLOB`, and `HLL` receivers, including write-policy flags.

[String, BLOB, and HLL functions →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/type-functions)

Control structures and postfix flags

`when` and `let`, plus the full postfix flag reference (`:NO_FAIL`, `:PARTIAL`, and more).

[Control structures and postfix flags →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/control-and-flags)

Type inference and limits

How AEL resolves types at parse time, compile limits, and name-collision disambiguation.

[Type inference and limits →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/type-inference-and-limits)

## 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, `let` variable names). Variable names cannot be quoted.
-   Reserved words (lowercase): `and`, `or`, `not`, `in`, `let`, `then`, `when`, `default`, `unknown`, `error`, `true`, `false`, and `exclusive`. 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 like `set` or `increment`. 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](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/paths#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: value` syntax, for example `log(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 example `abs(-3)`.
    -   Variable-argument calls of the same type (`min`, `max`) are positional, for example `min(3, 5, 7, 2)`.
    -   `geoCompare(a, b)` is positional, and both arguments are `GEO`.

## 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](#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](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/paths#collection-create-order-suffixes).

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](#literals)) | The stored value’s ordering |
| `$.m:UNORDERED.k.setTo(1)` (path create-order suffix, see [Collection create-order suffixes](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/paths#collection-create-order-suffixes)) | Ordering when the path creates a missing map on navigation |
| `$.m.getMaps():UNORDERED` (postfix flag, see [Postfix flags](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/control-and-flags#postfix-flags)) | Return shape of the read result only — does not change the stored map |

For regex literal flags and syntax, see [Regex literals](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/type-functions#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](#trilean-three-valued-logic)) |
| `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.

::: caution
A filter over a heterogeneous or evolving schema can exclude records with a missing or absent bin from query results with no error, because the missing operand evaluates to `unknown` rather than raising a parse error. When result completeness matters, add an explicit `exists()` check or a `when (…, default => …)` fallback for optional bins instead of relying on bare comparisons.
:::

For the `and` / `or` / `not` truth tables, see [Logical operators](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/operators#logical-operators).

Reserved literals `unknown` and `error` (see [Conditional: `when`](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/control-and-flags#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 `$.bin` because it can be inferred from the comparison.
-   `$.a + $.b + $.c == $.d and $.b > 3.1` doesn’t require types on `a`, `b`, `c`, or `d`: `b` must be a `FLOAT` (from the comparison with `3.1`), so `a`, `c`, and `d` must also be `FLOAT` from the addition and equality.
-   `$.left == $.right:STRING` does 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](#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](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/paths#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](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/paths#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](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/type-functions#string-path-functions)) and numeric casting (see [Path read terminals](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/functions#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:

```js
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.

[Paths and navigation →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference/paths)

Author AEL expressions

Filters, read projection, and write expressions on single-key, batch, and query commands.

[Author AEL expressions →](https://aerospike.com/docs/develop/client/sdk/concepts/ael/authoring-ael-expressions)