---
title: "Expressions Tutorial: Understanding Expressions"
description: "What expressions are, how Aerospike uses them, and the benefits they provide."
---

# Understanding expressions

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

This page is for developers using Aerospike client libraries. Complete [Setup](https://aerospike.com/docs/develop/tutorials/operations/expressions/setup) first. After reading this page, you can explain how Aerospike expressions are formed and how filter and operation expressions differ.

The examples on this page use plain, language-independent notation (similar in style to AEL) to focus on the underlying concepts before introducing client code. Concrete examples in Java, Python, Go, C#, Node.js, and Rust, with equivalent AEL text for Java and Python, begin in [Syntax and coding patterns](https://aerospike.com/docs/develop/tutorials/operations/expressions/syntax).

## Defining expressions

_An expression is a syntactic entity in a programming language that may be evaluated to determine its value._ [(Wikipedia)](https://en.wikipedia.org/wiki/Expression_\(computer_science\))

In other words, an expression evaluates to (or returns) a value. Some simple examples of an expression would be:

```text
5

7 + 3

2 > 1
```

Expressions can have:

-   constants:
    
    ```text
    5, "horse", [1, 2, 3]
    ```
    

In this example, they are an integer, a string and a list of numbers

-   variables:
    
    ```text
    var x = pow(b, c) + d
    ```
    
-   functions:
    
    ```text
    pow, mod, min
    ```
    
-   and operators:
    
    ```text
    ==, +, or
    ```
    

Expressions are composable. In other words, complex expressions can be formed from simpler expressions. For example:

```text
1 + min(2, a + 2) < sqrt(b)
```

An expression is not an assignment: An expression does not assign a value to a variable, but simply evaluates to a value which may be used in an assignment statement that assigns the value to a variable.

## Expressions in Aerospike

This section provides a higher level view of the capabilities and workings of expressions in Aerospike. The subsequent sections will drill down into the details.

### Evaluation context

Expressions are evaluated on the server for filtering conditions, reading and writing to bins, and configuring XDR replication. Therefore, an expression only works on server data entities such as the metadata and record data, and uses any constants that the client may provide. When used from the client library, expressions are created on the client and sent to the server in an API operation. Before sending, the client object format of an expression is converted to a wire format using the `build` operation.

### Components and scope

-   An expression is a combination of one or more constants, variables, functions, and operators that the programming language interprets … and computes to produce another value.\* [(Wikipedia)](https://en.wikipedia.org/wiki/Expression_\(computer_science\))

In Aerospike, expressions use bins, metadata functions and API calls, and values that are strongly typed as boolean, integer, float, string, list, map, blob, GeoJSON, or HyperLogLog. A host of arithmetic, logical, convenience, and API operations are available for these data.

See [Expressions](https://aerospike.com/docs/develop/expressions) for the list of supported components.

### Immutability of components

In Aerospike, an expression works on a transient copy, therefore evaluating an expression does not change the metadata or bins that are used in the expression.

For example, `$.firstName + " " + $.lastName` forms a result which joins the two bins but changes neither.

### Use of variables

A variable can be defined to represent a sub-expression for syntactic clarity and efficiency. A variable is first defined and initialized by assigning it to an expression, and then used as a substitute for the expression. In the example below, a variable `myvar` is defined and used in an expression `myexpr`:

```text
let(

    myvar = ($.a:INT + $.b) / min($.a, $.b),

    myexpr = ${myvar} +1 / ${myvar}

)

then (${myexpr})
```

### Conditional evaluation

An expression can be conditionally evaluated with an `if-then-else` like construct. Note the `else` case is always required. For example:

```text
let (

    myexpr = when(

        $.cond_1 => $.expr_1,

        $.cond_2 => $.expr_2,

        default => $.default

    )

then (...)
```

### Uses and types

Expressions are used in:

-   selection conditions aka predicates (called Filter Expressions),
-   operations (called Operation Expressions), and
-   XDR’s shipping configuration (called XDR Filter Expressions).

The functionality of expressions is the same, although the context determines their use. For example, Filter and XDR Filter Expressions are boolean expressions, whereas Operation Expressions can evaluate to any supported type.

Only Filter and Operation Expressions can be used in the client library and therefore will be the focus of this tutorial. See [Filtering XDR records with expressions](https://aerospike.com/docs/develop/expressions#filter-xdr-records-with-expressions) for the details of XDR Filter Expressions.

### AEL text authoring

Starting with Aerospike Database 8.2, Filter and Operation Expressions can also be authored as readable Aerospike Expression Language (AEL) text instead of a compiled `Exp` tree. The [Developer SDK](https://aerospike.com/docs/develop/client/sdk/) (Java and Python) accepts AEL strings directly in its query and operation builders: `.where(...)` for a filter expression, and `.selectFrom(...)` / `.upsertFrom(...)` / `.updateFrom(...)` for an operation expression.

This tutorial primarily uses the classic Java client and the `Exp.*` builder, with equivalent classic Python (`exp.*`), Go (`Exp*`), C# (`Exp.*`), Node.js (`exp.*`), and Rust (`aerospike::expressions::*`) examples alongside it, since that is the supported expression API for those clients. The Rust client’s builder functions are free functions rather than a fluent builder — for example, `eq(int_bin("a"), int_val(1))` instead of `Exp.eq(Exp.intBin("a"), Exp.val(1))`. Each filter and operation-expression example also shows the equivalent AEL text and how it would be authored with the Developer SDK (Java and Python only — Go, C#, Node.js, and Rust continue to use their respective expression builders). See the [AEL overview](https://aerospike.com/docs/develop/client/sdk/concepts/ael) and [AEL reference](https://aerospike.com/docs/develop/client/sdk/concepts/ael/reference) for the full grammar.

## Benefits of expressions

Here are some key benefits and capabilities that expressions enable:

-   Capabilities in expressions include:
    
    -   variables for syntactic clarity and efficiency,
    -   conditional evaluation,
    -   access to metadata and bin data, and
    -   access to powerful APIs and enhanced set of operators.
-   The enhanced filtering expressions allow records to be processed more efficiently by avoiding the need for potentially more expensive client or UDF based processing.
    
-   Reads and writes are now possible with Operation Expressions.
    
    -   in reads, this can eliminate the need to bring large amounts of data to the client with more precise ability to specify the data to be fetched.
    -   a bin can be updated with the results of an expression, which can eliminate having to read before update by allowing everything to happen on the server side in the same request including the read, processing for update, and update. This saves a round-trip and transfer of potentially large data. In a concurrent setting, this also avoids retries due to conflicts [see the R-M-W pattern](https://aerospike.com/docs/develop/tutorials/intro/read-modify-write-python).
-   Multi-step operations that can build on each other’s results are now possible through operation expressions.
    

## Next

Continue to [Syntax and coding patterns](https://aerospike.com/docs/develop/tutorials/operations/expressions/syntax).