# Expressions - Go

Jump to the [Code block](#code-block) for a combined complete example.

This page describes how to use expressions in single record commands.

[Aerospike expressions](https://aerospike.com/docs/develop/expressions) are a strongly typed, functional, domain-specific language for manipulating and comparing bins and record metadata.

For expression usage within multi-record requests, see [Batch operations](https://aerospike.com/docs/develop/client/go/usage/multi/batch/) and [Queries](https://aerospike.com/docs/develop/client/go/usage/multi/queries/primary/).

## Setup

The examples on this page use the following setup and record structure to illustrate the use of expressions in single record commands.

Setup and record structure examples

```go
import (

    "fmt"

    "github.com/aerospike/aerospike-client-go/v6"

)

// Establishes a connection to the server

client, err := aerospike.NewClient("127.0.0.1", 3000)

if err != nil {

    log.Fatal(err)

}

defer client.Close()

// Creates a key with the namespace "sandbox", set "ufodata", and user key 5001

key, err := aerospike.NewKey("sandbox", "ufodata", 5001)

if err != nil {

    log.Fatal(err)

}
```

The record structure:

```plaintext
+------+----------+----------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------+

| PK   | occurred | reported | posted   | report                                                                                                                                                                                                                 | location                                                   |

+------+----------+----------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------+

| 5001 | 20220531 | 20220601 | 20220601 | MAP('{"shape":["circle", "flash", "disc"], "summary":"Large flying disc flashed in the sky above the student union. Craziest thing I've ever seen!", "city":"Ann Arbor", "state":"Michigan", "duration":"5 minutes"}') | GeoJSON('{"type":"Point","coordinates":[42.2808,83.743]}') |

+------+----------+----------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------+
```

## Filter expressions

[Record filtering expressions](https://aerospike.com/docs/develop/expressions/#record-filtering-with-expressions) select records that satisfy a boolean expression and work with all single record commands (reads, writes, operations, and record UDFs), batch reads, and queries. Filters are only executed when a record exists. Filters are not executed when a record is created or is not found.

### Read

When using a filter expression on a read command, the expression is defined within the read policy.

The following example creates a filter expression that checks the length of the `shape` list in the `report` map and only returns if there are more than two shapes.

```go
// Create the policy

policy := aerospike.NewPolicy()

// Build the expression

policy.FilterExpression = aerospike.ExpGreater(

    aerospike.ExpListSize(

        aerospike.ExpMapGetByKey(aerospike.MapReturnType.VALUE, aerospike.ExpTypeLIST, aerospike.ExpStringVal("shape"), aerospike.ExpMapBin("report"))),

    aerospike.ExpIntVal(2))

// Read the record

record, err := client.Get(policy, key)

if err != nil {

    log.Fatal(err)

}

// Do something

fmt.Printf("Record: %v", record.Bins)
```

### Write

When using a filter expression on a write command, the expression is defined within the write policy.

The following example creates a filter expression that checks if `occurred` is later than `20211231` and `posted` exists. If the filter returns true, a `recent` key with the value `true` will be added to the `report` map.

```go
// Create the policy

writePolicy := aerospike.NewWritePolicy(0,0)

// Build the expression

writePolicy.FilterExpression = aerospike.ExpAnd(

    aerospike.ExpGreater(aerospike.ExpIntBin("occurred"), aerospike.ExpIntVal(20211231)),

    aerospike.ExpBinExists("posted"))

// Update the record

_, err = client.Operate(writePolicy, key, aerospike.MapPutOp(aerospike.DefaultMapPolicy(), "report", aerospike.NewValue("recent"), aerospike.NewValue(true)))

if err != nil {

    log.Fatal(err)

}
```

## Operation expressions

[Operation expressions](https://aerospike.com/docs/develop/expressions#operation-expressions) are bin operations that atomically compute a value using information in the record or from data supplied by the expression itself.

The result is either returned to the client, in a read expression, or written to a specified bin, in a write expression.

You can define a [filter expression](https://aerospike.com/docs/develop/expressions/#record-filtering-with-expressions) in the write policy of the `operate` method to determine the execution of a [bin operation](https://aerospike.com/docs/develop/client/go/usage/atomic/multi) using an operation expression.

### Read

The read expression operation computes an expression, and returns that value. A defined `name` in the operation can be used as the synthetic bin name when retrieving results.

The following example takes the [Read](#read) filter expression example from above and changes the scenario slightly. This command computes the length of the `shape` list in the `report` map and returns the value in a synthetic bin called `numShapes`.

```go
// Build the expression

exp := aerospike.ExpListSize(

    aerospike.ExpMapGetByKey(aerospike.MapReturnType.VALUE, aerospike.ExpTypeLIST, aerospike.ExpStringVal("shape"), aerospike.ExpMapBin("report")))

// Read the record

record, err := client.Operate(nil, key, aerospike.ExpReadOp("numShapes", exp, aerospike.ExpReadFlagDefault))

if err != nil {

    log.Fatal(err)

}

// Do something

fmt.Printf("Record: %v", record.Bins)
```

### Write

The write expression operation computes an expression and writes that value to a bin.

The following example takes the [Write](#write) filter expression example from above and changes the scenario slightly. Using the same criteria to compute a `recent` value, `reported` bin value and `posted` bin exists, this command updates the `report` map with the `recent` value, `true` or `false`.

```go
// Build the expression

exp := aerospike.ExpMapPut(aerospike.DefaultMapPolicy(), aerospike.ExpStringVal("recent"),

        aerospike.ExpAnd(

            aerospike.ExpGreater(aerospike.ExpIntBin("occurred"), aerospike.ExpIntVal(20211231)),

            aerospike.ExpBinExists("posted")),

        aerospike.ExpMapBin("report"))

// Update the record

_, err = client.Operate(nil, key, aerospike.ExpWriteOp("report", exp, aerospike.ExpWriteFlagDefault))

if err != nil {

    log.Fatal(err)

}
```

## Code block

Expand this section for a single code block to create an operation expression

```go
import (

    "fmt"

    "github.com/aerospike/aerospike-client-go/v6"

)

func main() {

    // Establishes a connection to the server

    client, err := aerospike.NewClient("127.0.0.1", 3000)

    if err != nil {

        log.Fatal(err)

    }

    defer client.Close()

    // Creates a key with the namespace "sandbox", set "ufodata", and user key 5001

    key, err := aerospike.NewKey("sandbox", "ufodata", 5001)

    if err != nil {

        log.Fatal(err)

    }

    // Build the expression

    exp := aerospike.ExpMapPut(aerospike.DefaultMapPolicy(), aerospike.ExpStringVal("recent"),

            aerospike.ExpAnd(

                aerospike.ExpGreater(aerospike.ExpIntBin("occurred"), aerospike.ExpIntVal(20211231)),

                aerospike.ExpBinExists("posted")),

            aerospike.ExpMapBin("report"))

    // Update the record

    _, err = client.Operate(nil, key, aerospike.ExpWriteOp("report", exp, aerospike.ExpWriteFlagDefault))

    if err != nil {

        log.Fatal(err)

    }

}
```

## History of expressions in Aerospike Database

-   Secondary index expressions introduced in Database 8.1.0
-   Operation expressions introduced in Database 5.6.0
-   XDR filter expressions introduced in Database 5.3.0
-   Record filter expressions introduced in Database 5.2.0