---
title: "Bin operations"
description: "Learn to perform atomic single and multiple bin operations using the Aerospike Go client's operate method."
---

# Bin operations

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

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

## Setup

The following examples will use the setup and record below to illustrate single record command operations in an Aerospike database.

```go
import (

    "fmt"

    "log"

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

)

// 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]}') |

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

## Operations

Use the Aerospike Client API to perform separate [operations](https://aerospike.com/docs/develop/learn/single) on one or multiple bins in a record within a single transaction. This feature performs an atomic modification then returns the result. The table below shows some of the bin operations available for operate transactions.

Operations for List, Map, String, Blob/Bytes, Geospatial, and HyperLogLog data types see [Scalar data types](https://aerospike.com/docs/develop/data-types/scalar).

| Data Type | Operation | Description |
| :-- | :-: | :-- |
| All | `op_put` | Upsert (create or update) a bin. Also called `write`. |
| All | `op_get` | Read a bin. Also called `read`. |
| All | `op_touch` | Increase the generation counter for a record. |
| All | `op_delete` | Remove a record from the database. |
| Integer  
Float | `op_add` | Add (or subtract) a value. Used to implement counters. Also called `increment`. |
| String | `op_append`  
`op_prepend` | Modify a string. For Unicode-aware transforms, see [String operations](https://aerospike.com/docs/develop/data-types/string) (Database 8.2.0 and later). |

Operations are performed in user defined order.

`Operate` applies every operation to one record as a single atomic command. If any operation fails, the server rejects the command and leaves the record unchanged. There is no partial success across operations in the same call.

Map and List item flags are a separate layer. They control what happens when a specific key or index already exists, and they can allow some items to be skipped without failing the command.

### Single operation

All of the operations in the table above, along with [collection data type (CDT)](https://aerospike.com/docs/develop/data-types/collections), [Blob/Bytes](https://aerospike.com/docs/develop/data-types/blob), [Geospatial](https://aerospike.com/docs/develop/data-types/geospatial), [HyperLogLog](https://aerospike.com/docs/develop/data-types/hll), and [String operations](https://aerospike.com/docs/develop/data-types/string/operations) (Database 8.2.0 and later), can be executed as a single operation with the `Operate` method. For the Go client’s `Str*Op`/`ExpString*` surface, see [Go String operations](https://aerospike.com/docs/develop/client/go/usage/string).

The following example creates a map policy for a `KEY_ORDERED` map, then applies that policy to the `report` bin. A `KEY_ORDERED` map provides faster access than the default `UNORDERED` map. This example passes `nil` to use the default policy, but a write policy could be passed instead.

Use `NewMapPolicyWithFlags` on Database 4.3 and later. `NewMapPolicy` with `MapWriteMode` exists only for earlier servers and is not the API to use for current deployments.

```go
// Create KEY_ORDERED map policy

mapPolicy := aerospike.NewMapPolicyWithFlags(aerospike.MapOrder.KEY_ORDERED, aerospike.MapWriteFlagsDefault)

// Update the record

_, err = client.Operate(nil, key, aerospike.MapSetPolicyOp(mapPolicy, "report"))

if err != nil {

    log.Fatal(err)

}
```

### Multiple operations

Multiple operations can be combined in a single transaction when one or more bins need to be updated or read.

The following example inserts the `posted` bin with value `20220602`, updates the `city` inside the `report` bin to `"Ypsilanti"`, and reads the `report` bin in a single transaction.

```go
// Create posted bin to insert

posted := aerospike.NewBin("posted", 20220602)

// Update the record

record, err := client.Operate(nil, key,

    aerospike.PutOp(posted),

    aerospike.MapPutOp(aerospike.DefaultMapPolicy(), "report", aerospike.NewValue("city"), aerospike.NewValue("Ypsilanti")),

    aerospike.GetBinOp("report"))

if err != nil {

    log.Fatal(err)

}

// Do something

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

### Map write flags

`RecordExistsAction` on a write policy applies to the whole record. Map write flags apply to a single map key.

| Flag | Description |
| --- | --- |
| `MapWriteFlagsDefault` | Create the key if it is missing. Overwrite it if it exists. |
| `MapWriteFlagsCreateOnly` | Create the key only if it does not already exist. |
| `MapWriteFlagsUpdateOnly` | Overwrite the key only if it already exists. |
| `MapWriteFlagsNoFail` | Do not fail the command when a flag denies an item. |
| `MapWriteFlagsPartial` | With `MapWriteFlagsNoFail`, commit the items that pass and skip the rest. |

Combine flags with `|`. `MapWriteFlags` require Database 4.3 or later.

```go
createOnly := aerospike.NewMapPolicyWithFlags(

    aerospike.MapOrder.UNORDERED,

    aerospike.MapWriteFlagsCreateOnly,

)

_, err = client.Operate(nil, key,

    aerospike.MapPutOp(createOnly, "report", aerospike.NewValue("city"), aerospike.NewValue("Ypsilanti")),

)

if err != nil {

    log.Fatal(err)

}
```

### Returning from `operate()`

It’s important to understand how the `operate` method returns data, since `operate` accepts a variety of operations and deals with both reads and writes in a single call.

Examples of operations and results:

-   A basic `put` or `write` operation does not return anything by default, though it can be set to return `null` through a write policy.
-   A map or list `modify` operation returns the map or list size for the `bin_name`.
-   A `get` or `read` operation returns the value for the `bin_name`.

See [Bitwise operations](https://aerospike.com/docs/develop/data-types/blob), [List operations](https://aerospike.com/docs/develop/data-types/collections/list/operations), [Map operations](https://aerospike.com/docs/develop/data-types/collections/map/operations), [String operations](https://aerospike.com/docs/develop/data-types/string/operations), [HLL operations](https://aerospike.com/docs/develop/data-types/hll#operations), and [Expressions](https://aerospike.com/docs/develop/expressions) for more information about return values.

The `operate` method takes the results of all the operations executed within the call and groups them together by `bin_name`. If a specific `bin_name` has multiple results, such as an `operate` call containing multiple operations that return results for a single `bin_name`, a list is created containing the results of each operation. If a `bin_name` has a single value, the `bin_name` value is returned as expected.

When grouped by `bin_name`, the way results are accessed will vary based on what operations are performed.

Some write operations do not return a result by default, which can shift the offset of later results in the same bin. Set `WritePolicy.RespondPerEachOp` to `true` so every operation returns a result.

::: note
`RespondPerEachOp` requires Database 3.10 or later. Map write flags require Database 4.3 or later. `NewMapPolicyWithFlagsAndPersistedIndex` requires Database 7.0 or later.
:::

## Code block

Expand this section for a single code block to create a transaction operation

```go
import (

    "fmt"

    "log"

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

)

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)

    }

    // Create posted bin to insert

    posted := aerospike.NewBin("posted", 20220602)

    // Update the record

    record, err := client.Operate(nil, key,

        aerospike.PutOp(posted),

        aerospike.MapPutOp(aerospike.DefaultMapPolicy(), "report", aerospike.NewValue("city"), aerospike.NewValue("Ypsilanti")),

        aerospike.GetBinOp("report"))

    if err != nil {

        log.Fatal(err)

    }

    // Do something

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

}
```