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