---
title: "Update"
description: "Learn how to update nested Aerospike document records in Go using MapPutOp and CDT context paths."
---

# Update

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

## Create a document record

The following example demonstrates reading a document record with a JSON helper library. In Aerospike, JSON documents are handled as a [Collection Data Type (CDT)](https://aerospike.com/docs/develop/data-types/collections). A JSON object is equivalent to a [map](https://aerospike.com/docs/develop/data-types/collections/map), and a JSON array is equivalent to a [list](https://aerospike.com/docs/develop/data-types/collections/list).

In this example, we create the following JSON document:

```json
employees = [{"id": "09", "name": "Nitin", "department": "Finance"},

             {"id": "10", "name": "Jonathan", "department": "Human Resources"},

             {"id": "11", "name": "Caitlin", "department": "Engineering"}]
```

The JSON document is added to a bin called `employees` which is of data type [list](https://aerospike.com/docs/develop/data-types/collections/list). There are some advantages to holding an entire document in a single bin, rather than spreading out the document’s fields over multiple bins. There is less metadata overhead when namespaces contain fewer, larger bins.

### Setup

Import the necessary helpers, create a client connection, and create a key.

```go
package main

import (

  "encoding/json"

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

  "log"

  "os"

  "runtime"

  "time"

)

// Policy Global policy definitions

var Policy = as.NewPolicy()

var WritePolicy = as.NewWritePolicy(0, 0)

func main() {

  host := "localhost"

  port := 3000

  // use all cpus in the system for concurrency

  runtime.GOMAXPROCS(runtime.NumCPU())

  log.SetOutput(os.Stdout)

  cp := as.NewClientPolicy()

  cp.Timeout = 3 * time.Second

  Client, err := as.NewClientWithPolicy(cp, host, port)

  if err != nil {

    panic(err)

  }

  namespace := "test"

  set := "table1"

  // clean out old record

  key, _ := as.NewKey(namespace, set, "key5")

  deleted, err := Client.Delete(WritePolicy, key)

  if deleted {

    log.Println("Deleted key:", key.Value())

  } else {

    log.Println("Did not delete key", key.Value())

  }

  if err != nil {

    log.Println("Warning - delete failed with error:", err)

  }

  documentExampleUpdate(Client, key)

  log.Println("Example finished successfully.")

}
```

Prepare the JSON document to be sent to Aerospike.

```go
func documentExampleUpdate(client *as.Client, key *as.Key) {

    // create a slice of maps

  employeeList := []map[string]string{

    {"id": "09", "name": "Nitin", "department": "Finance"},

    {"id": "10", "name": "Jonathan", "department": "HumanResources"},

    {"id": "11", "name": "Caitlin", "department": "Engineering"},

  }

  employees := map[string]interface{}{

    "employees_list": employeeList,

  }

  // create a JSON doc of the employees

  doc, _ := json.Marshal(employees)

  log.Println("Generated JSON doc: ", string(doc))

  // unmarshal the JSON

  emps := make(map[string]interface{}, 1)

  if err := json.Unmarshal(doc, &emps); err != nil {

    panic(err)

  }

  log.Println("Restored data structure for JSON doc: ", emps)
```

### Write

Write the document to Aerospike.

```go
// Store the restored structure in an Aerospike bin, then write the bin to the record.

  bin := as.NewBin("Employees", emps)

  log.Println("Attempting to insert record with key'", key.Value(), "'...")

  if err := client.PutBins(WritePolicy, key, bin); err != nil {

    panic(err)

  }

  log.Println("Insert Successful.")
```

### Update

Update the newly created document.

```go
// Create the update request.  Change the index[2] employee's

    // department from "Engineering" to "Support".

    // First create the context path to navigate to the department field.

    // Define a context to navigate the highest level map with key "employees_list".

    ctx1 := as.CtxMapKey(as.NewValue("employees_list"))

    // Then navigate the list to index 2.

    ctx2 := as.CtxListIndex(2)

    // we need to provide a MapPolicy - we will use the default

    mapPolicy := as.DefaultMapPolicy()

    // Finally, call Operate, with a MapPutOp operation using the above contexts to request

    // the change to the "department" key's value to "Support".

    record, err := client.Operate(WritePolicy,

        key,

        as.MapPutOp(mapPolicy, bin.Name, "department", "Support", ctx1, ctx2))

    if err != nil {

        panic(err)

    }
```

### Read

Read the newly updated document.

```go
// read back the record from the database again and verify we have changed the value correctly

    record, err = client.Get(Policy, key, bin.Name)

    if err != nil {

        panic(err)

    }

    received := record.Bins[bin.Name].(map[interface{}]interface{})

    receivedEmployees := received["employees_list"].([]interface{})

    log.Println("Record read back from database: ", received)

    for index, employeeRecord := range receivedEmployees {

        employeeMap := employeeRecord.(map[interface{}]interface{})

        log.Println("Employee ", index)

        log.Println("\\tID: ", employeeMap["id"])

        log.Println("\\tName: ", employeeMap["name"])

        log.Println("\\tDepartment: ", employeeMap["department"])

    }

}
```

## Code block

Expand this section for a single code block to update a document record.

```go
package main

import (

  "encoding/json"

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

  "log"

  "os"

  "runtime"

  "time"

)

// Policy Global policy definitions

var Policy = as.NewPolicy()

var WritePolicy = as.NewWritePolicy(0, 0)

func main() {

  host := "localhost"

  port := 3000

  // use all cpus in the system for concurrency

  runtime.GOMAXPROCS(runtime.NumCPU())

  log.SetOutput(os.Stdout)

  cp := as.NewClientPolicy()

  cp.Timeout = 3 * time.Second

  Client, err := as.NewClientWithPolicy(cp, host, port)

  if err != nil {

    panic(err)

  }

  namespace := "test"

  set := "table1"

  // clean out old record

  key, _ := as.NewKey(namespace, set, "key5")

  deleted, err := Client.Delete(WritePolicy, key)

  if deleted {

    log.Println("Deleted key:", key.Value())

  } else {

    log.Println("Did not delete key", key.Value())

  }

  if err != nil {

    log.Println("Warning - delete failed with error:", err)

  }

  documentExampleUpdate(Client, key)

  log.Println("Example finished successfully.")

}

func documentExampleUpdate(client *as.Client, key *as.Key) {

    // create a slice of maps

  employeeList := []map[string]string{

    {"id": "09", "name": "Nitin", "department": "Finance"},

    {"id": "10", "name": "Jonathan", "department": "HumanResources"},

    {"id": "11", "name": "Caitlin", "department": "Engineering"},

  }

  employees := map[string]interface{}{

    "employees_list": employeeList,

  }

  // create a JSON doc of the employees

  doc, _ := json.Marshal(employees)

  log.Println("Generated JSON doc: ", string(doc))

  // unmarshal the JSON

  emps := make(map[string]interface{}, 1)

  if err := json.Unmarshal(doc, &emps); err != nil {

    panic(err)

  }

  log.Println("Restored data structure for JSON doc: ", emps)

    // Store the restored structure in an Aerospike bin, then write the bin to the record.

  bin := as.NewBin("Employees", emps)

  log.Println("Attempting to insert record with key'", key.Value(), "'...")

  if err := client.PutBins(WritePolicy, key, bin); err != nil {

    panic(err)

  }

  log.Println("Insert Successful.")

    // Create the update request.  Change the index[2] employee's

    // department from "Engineering" to "Support".

    // First create the context path to navigate to the department field.

    // Define a context to navigate the highest level map with key "employees_list".

    ctx1 := as.CtxMapKey(as.NewValue("employees_list"))

    // Then navigate the list to index 2.

    ctx2 := as.CtxListIndex(2)

    // we need to provide a MapPolicy - we will use the default

    mapPolicy := as.DefaultMapPolicy()

    // Finally, call Operate, with a MapPutOp operation using the above contexts to request

    // the change to the "department" key's value to "Support".

    record, err := client.Operate(WritePolicy,

        key,

        as.MapPutOp(mapPolicy, bin.Name, "department", "Support", ctx1, ctx2))

    if err != nil {

        panic(err)

    }

    // read back the record from the database again and verify we have changed the value correctly

    record, err = client.Get(Policy, key, bin.Name)

    if err != nil {

        panic(err)

    }

    received := record.Bins[bin.Name].(map[interface{}]interface{})

    receivedEmployees := received["employees_list"].([]interface{})

    log.Println("Record read back from database: ", received)

    for index, employeeRecord := range receivedEmployees {

        employeeMap := employeeRecord.(map[interface{}]interface{})

        log.Println("Employee ", index)

        log.Println("\\tID: ", employeeMap["id"])

        log.Println("\\tName: ", employeeMap["name"])

        log.Println("\\tDepartment: ", employeeMap["department"])

    }

}
```