Update
Jump to the 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). A JSON object is equivalent to a map, and a JSON array is equivalent to a list.
In this example, we create the following JSON document:
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. 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.
package main
import ( "encoding/json" as "github.com/aerospike/aerospike-client-go/v6" "log" "os" "runtime" "time")
// Policy Global policy definitionsvar 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.
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.
// 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.
// 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.
// 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.
package main
import ( "encoding/json" as "github.com/aerospike/aerospike-client-go/v6" "log" "os" "runtime" "time")
// Policy Global policy definitionsvar 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"]) }}