# Bin operations

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"

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

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

## 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, Blob/Bytes, Geospatial, and HyperLogLog data types can be found [here](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. |

Operations are performed in user defined order.

### Single operation

All of the operations in the table above, along with [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), and [HyperLogLog](https://aerospike.com/docs/develop/data-types/hll) operations, can be executed as a single operation with the `operate` method.

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 `null` to use the default policy, but a write policy could be passed instead.

```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)
```

### 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), [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.

## Code block

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

```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)

    }

    // 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)

}
```