Single-record commands
Aerospike provides simple interfaces for reading data from and writing data to an Aerospike cluster. They cover the standard CRUD (create, read, update, delete) use cases.
Every Aerospike client can perform the following single-record commands, no matter which language it’s written in:
| Command | Description |
|---|---|
put | Write a record. Performs the equivalent of create, update or replace, depending on the write policy given to the write command. |
get | Read the record. Specific bins can be selected. |
operate | Executes multiple bin operations atomically and in isolation as a single record command. |
touch | Increment the generation counter and extend its time-to-live (TTL) |
delete | Remove a record from the database. Generates a tombstone when using the durable-delete policy. |
Filtering operations
A command can be conditionally applied, based on the result of a record filter expression. If the filter expression evaluates to true, the operation executes.
Code examples of record operations
Every record is identified by a key consisting of a namespace, an optional set, and a user key. In the following examples, the key is ("test", "demo", "user1"), placing the record in the demo set of the test namespace.
A record can also be created without a set by passing null (or None) as the set component. Such records belong to the null set. Records in the null set are fully accessible through single-record commands (put, get, operate, touch, delete) and batch commands, but cannot be targeted by a secondary index query unless the index covers the entire namespace. You can prevent null-set records from being created by setting disallow-null-setname to true.
The following examples demonstrate put (create and merge-style update), get, operate (atomic multi-bin updates in one round trip), touch, and delete on a single record.
They use a record with a string bin, an integer bin, and a map bin:
| Bin | Type | Value |
|---|---|---|
name | string | "Alice" |
visits | integer | 1 |
prefs | map | {"theme": "dark", "lang": "en"} |
Each section below shows an excerpt. See the Code block at the bottom of the page for the full, continuous program in each language.
Create a record
Use put to write a new record. By default, put creates the record if it does not exist, or merges bins into the existing record if it does. This behavior is controlled by the write policy’s recordExistsAction, which defaults to UPDATE (upsert). Other options include CREATE_ONLY, UPDATE_ONLY, and REPLACE.
Map<String, Object> prefs = new HashMap<>();prefs.put("theme", "dark");prefs.put("lang", "en");
// Default upsert behavior (RecordExistsAction.UPDATE)// WritePolicy wp = new WritePolicy();// wp.recordExistsAction = RecordExistsAction.UPDATE;// client.put(wp, key, ...);
client.put(null, key, new Bin("name", "Alice"), new Bin("visits", 1), new Bin("prefs", prefs));bins = { "name": "Alice", "visits": 1, "prefs": {"theme": "dark", "lang": "en"},}
# Default upsert behavior (POLICY_EXISTS_UPDATE)# policy = {"exists": aerospike.POLICY_EXISTS_UPDATE}# client.put(key, bins, policy=policy)
client.put(key, bins)prefs := map[interface{}]interface{}{ "theme": "dark", "lang": "en",}
// Default upsert behavior (as.UPDATE)// wp := as.NewWritePolicy(0, 0)// wp.RecordExistsAction = as.UPDATE// err = client.PutBins(wp, key, ...)
err = client.PutBins(nil, key, as.NewBin("name", "Alice"), as.NewBin("visits", 1), as.NewBin("prefs", prefs))as_hashmap prefs;as_hashmap_init(&prefs, 2);as_stringmap_set_str(&prefs, "theme", "dark");as_stringmap_set_str(&prefs, "lang", "en");
as_record rec;as_record_inita(&rec, 3);as_record_set_str(&rec, "name", "Alice");as_record_set_int64(&rec, "visits", 1);as_record_set_map(&rec, "prefs", (as_map *)&prefs);
// Default upsert behavior (AS_POLICY_EXISTS_UPDATE)// as_policy_write wp;// as_policy_write_init(&wp);// wp.exists = AS_POLICY_EXISTS_UPDATE;// aerospike_key_put(&as, &err, &wp, &key, &rec);
aerospike_key_put(&as, &err, NULL, &key, &rec);as_record_destroy(&rec);var prefs = new Dictionary<string, object> { { "theme", "dark" }, { "lang", "en" }};
// Default upsert behavior (RecordExistsAction.UPDATE)// WritePolicy wp = new WritePolicy();// wp.recordExistsAction = RecordExistsAction.UPDATE;// client.Put(wp, key, ...);
client.Put(null, key, new Bin("name", "Alice"), new Bin("visits", 1), new Bin("prefs", prefs));const bins = { name: "Alice", visits: 1, prefs: { theme: "dark", lang: "en" },};
// Default upsert behavior (Aerospike.policy.exists.UPDATE)// const wp = new Aerospike.WritePolicy({// exists: Aerospike.policy.exists.UPDATE,// });// await client.put(key, bins, {}, wp);
await client.put(key, bins);Read a record
Use get to read the full record (metadata and all bins), or select specific bins.
Record record = client.get(null, key);System.out.format("Record: %s%n", record.bins);(key_, meta, bins) = client.get(key)print("Record:", bins)record, err := client.Get(nil, key)fmt.Printf("Record: %v\n", record.Bins)#include <stdio.h>
as_record *p_rec = NULL;aerospike_key_get(&as, &err, NULL, &key, &p_rec);printf("Record: name=%s visits=%lld\n", as_record_get_str(p_rec, "name"), (long long)as_record_get_int64(p_rec, "visits"));as_record_destroy(p_rec);Record record = client.Get(null, key);Console.WriteLine("Record: {0}", record.bins);const record = await client.get(key);console.info("Record:", record.bins);Merge-update bins with put
Use put again to change one or more bins. With default write policies, the client merges new bins into the existing record and leaves other bins unchanged (this is not a full replace of every bin unless you use a replace-style policy).
client.put(null, key, new Bin("name", "Alice K."));client.put(key, {"name": "Alice K."})err = client.PutBins(nil, key, as.NewBin("name", "Alice K."))as_record upd;as_record_inita(&upd, 1);as_record_set_str(&upd, "name", "Alice K.");aerospike_key_put(&as, &err, NULL, &key, &upd);as_record_destroy(&upd);client.Put(null, key, new Bin("name", "Alice K."));await client.put(key, { name: "Alice K." });Atomic updates with operate
Use operate to execute multiple bin operations atomically in a single command.
The following example increments the visits counter, updates a value inside the
prefs map, and reads both bins — all in one round trip.
Record record = client.operate(null, key, Operation.add(new Bin("visits", 1)), MapOperation.put(MapPolicy.Default, "prefs", Value.get("lang"), Value.get("fr")), Operation.get("visits"), Operation.get("prefs"));
System.out.format("visits: %s, prefs: %s%n", record.getValue("visits"), record.getValue("prefs"));ops = [ op.increment("visits", 1), mop.map_put("prefs", "lang", "fr"), op.read("visits"), op.read("prefs"),]
(key_, meta, bins) = client.operate(key, ops)print("visits:", bins["visits"], "prefs:", bins["prefs"])addVisits := as.NewBin("visits", 1)
record, err := client.Operate(nil, key, as.AddOp(addVisits), as.MapPutOp(as.DefaultMapPolicy(), "prefs", as.NewValue("lang"), as.NewValue("fr")), as.GetBinOp("visits"), as.GetBinOp("prefs"))
fmt.Printf("visits: %v, prefs: %v\n", record.Bins["visits"], record.Bins["prefs"])as_operations ops;as_operations_inita(&ops, 4);as_operations_add_incr(&ops, "visits", 1);
as_string lang_key;as_string_init(&lang_key, "lang", false);as_string lang_val;as_string_init(&lang_val, "fr", false);as_operations_map_put(&ops, "prefs", NULL, NULL, (as_val *)&lang_key, (as_val *)&lang_val);
as_operations_add_read(&ops, "visits");as_operations_add_read(&ops, "prefs");
as_record *p_rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops, &p_rec);as_operations_destroy(&ops);as_record_destroy(p_rec);Record record = client.Operate(null, key, Operation.Add(new Bin("visits", 1)), MapOperation.Put(MapPolicy.Default, "prefs", Value.Get("lang"), Value.Get("fr")), Operation.Get("visits"), Operation.Get("prefs"));
Console.WriteLine("visits: {0}, prefs: {1}", record.GetValue("visits"), record.GetValue("prefs"));const ops = [ op.incr("visits", 1), maps.put("prefs", "lang", "fr"), op.read("visits"), op.read("prefs"),];
const record = await client.operate(key, ops);console.info("visits:", record.bins.visits, "prefs:", record.bins.prefs);Touch a record
Use touch to increment the record’s generation counter and optionally reset its time-to-live (TTL).
WritePolicy touchPolicy = new WritePolicy();touchPolicy.expiration = 300; // TTL in seconds
client.touch(touchPolicy, key);client.touch(key, 300) # TTL in secondstouchPolicy := as.NewWritePolicy(0, 300) // generation, TTL in secondserr = client.Touch(touchPolicy, key)as_operations ops;as_operations_inita(&ops, 1);as_operations_add_touch(&ops);ops.ttl = 300; // TTL in seconds
as_record *p_rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops, &p_rec);as_operations_destroy(&ops);as_record_destroy(p_rec);WritePolicy touchPolicy = new WritePolicy();touchPolicy.expiration = 300; // TTL in seconds
client.Touch(touchPolicy, key);await client.operate(key, [op.touch(300)]);Delete a record
Use delete (or remove) to delete a record. Enable durableDelete in the write policy to write a tombstone that prevents the record from resurrecting on a cold restart. See Durable Deletes for details.
// Durable delete:// WritePolicy deletePolicy = new WritePolicy();// deletePolicy.durableDelete = true;// client.delete(deletePolicy, key);
WritePolicy removePolicy = new WritePolicy(); // empty / defaultclient.delete(removePolicy, key);# Durable delete:# durable_policy = {"durable_delete": True}# client.remove(key, policy=durable_policy)
remove_policy = {} # empty write policyclient.remove(key, policy=remove_policy)// Durable delete:// deletePolicy := as.NewWritePolicy(0, 0)// deletePolicy.DurableDelete = true// _, err = client.Delete(deletePolicy, key)
removePolicy := as.NewWritePolicy(0, 0) // empty write policy_, err = client.Delete(removePolicy, key)// Durable delete:// as_policy_remove deletePolicy;// as_policy_remove_init(&deletePolicy);// deletePolicy.durable_delete = true;// aerospike_key_remove(&as, &err, &deletePolicy, &key);
as_policy_remove removePolicy;as_policy_remove_init(&removePolicy);aerospike_key_remove(&as, &err, &removePolicy, &key);// Durable delete:// WritePolicy deletePolicy = new WritePolicy();// deletePolicy.durableDelete = true;// client.Delete(deletePolicy, key);
WritePolicy removePolicy = new WritePolicy(); // empty / defaultclient.Delete(removePolicy, key);const Aerospike = await import("aerospike");
// Durable delete:// const deletePolicy = new Aerospike.WritePolicy({ durableDelete: true });// await client.remove(key, deletePolicy);
const removePolicy = new Aerospike.WritePolicy(); // empty write policyawait client.remove(key, removePolicy);Usage note for all examples
All full record read and write commands accept policy parameters: Max Retries and Total Timeout.
Write operations take an optional time-to-live (TTL) parameter that specifies how long to protect a record from automatic eviction by the system. Set the TTL to -1 to tell Aerospike to never evict that data.
Code block
Expand for the full single-record operations example
import com.aerospike.client.AerospikeClient;import com.aerospike.client.Bin;import com.aerospike.client.Key;import com.aerospike.client.Record;import com.aerospike.client.Value;import com.aerospike.client.Operation;import com.aerospike.client.cdt.MapPolicy;import com.aerospike.client.cdt.MapOperation;import com.aerospike.client.policy.WritePolicy;
import java.util.HashMap;import java.util.Map;
// ConnectAerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
Key key = new Key("test", "demo", "user1");
// UpsertMap<String, Object> prefs = new HashMap<>();prefs.put("theme", "dark");prefs.put("lang", "en");
client.put(null, key, new Bin("name", "Alice"), new Bin("visits", 1), new Bin("prefs", prefs));
// ReadRecord record = client.get(null, key);System.out.format("Record: %s%n", record.bins);
// Merge-update (put)client.put(null, key, new Bin("name", "Alice K."));
// Update (operate)record = client.operate(null, key, Operation.add(new Bin("visits", 1)), MapOperation.put(MapPolicy.Default, "prefs", Value.get("lang"), Value.get("fr")), Operation.get("visits"), Operation.get("prefs"));
System.out.format("visits: %s, prefs: %s%n", record.getValue("visits"), record.getValue("prefs"));
// TouchWritePolicy touchPolicy = new WritePolicy();touchPolicy.expiration = 300;
client.touch(touchPolicy, key);
// Durable delete:// WritePolicy deletePolicy = new WritePolicy();// deletePolicy.durableDelete = true;// client.delete(deletePolicy, key);
WritePolicy removePolicy = new WritePolicy(); // empty / defaultclient.delete(removePolicy, key);
client.close();import aerospikefrom aerospike_helpers.operations import operations as opfrom aerospike_helpers.operations import map_operations as mop
# Connectconfig = {"hosts": [("127.0.0.1", 3000)]}client = aerospike.client(config).connect()
key = ("test", "demo", "user1")
# Upsertbins = { "name": "Alice", "visits": 1, "prefs": {"theme": "dark", "lang": "en"},}
client.put(key, bins)
# Read(key_, meta, bins) = client.get(key)print("Record:", bins)
# Merge-update (put)client.put(key, {"name": "Alice K."})
# Update (operate)ops = [ op.increment("visits", 1), mop.map_put("prefs", "lang", "fr"), op.read("visits"), op.read("prefs"),]
(key_, meta, bins) = client.operate(key, ops)print("visits:", bins["visits"], "prefs:", bins["prefs"])
# Touchclient.touch(key, 300)
# Durable delete:# durable_policy = {"durable_delete": True}# client.remove(key, policy=durable_policy)
remove_policy = {} # empty write policyclient.remove(key, policy=remove_policy)
client.close()import ( "fmt" "log" as "github.com/aerospike/aerospike-client-go/v6")
func main() { // Connect client, err := as.NewClient("127.0.0.1", 3000) if err != nil { log.Fatal(err) } defer client.Close()
key, _ := as.NewKey("test", "demo", "user1")
// Upsert prefs := map[interface{}]interface{}{ "theme": "dark", "lang": "en", }
err = client.PutBins(nil, key, as.NewBin("name", "Alice"), as.NewBin("visits", 1), as.NewBin("prefs", prefs)) if err != nil { log.Fatal(err) }
// Read record, err := client.Get(nil, key) if err != nil { log.Fatal(err) } fmt.Printf("Record: %v\n", record.Bins)
// Merge-update (put) err = client.PutBins(nil, key, as.NewBin("name", "Alice K.")) if err != nil { log.Fatal(err) }
// Update (operate) addVisits := as.NewBin("visits", 1)
record, err = client.Operate(nil, key, as.AddOp(addVisits), as.MapPutOp(as.DefaultMapPolicy(), "prefs", as.NewValue("lang"), as.NewValue("fr")), as.GetBinOp("visits"), as.GetBinOp("prefs")) if err != nil { log.Fatal(err) } fmt.Printf("visits: %v, prefs: %v\n", record.Bins["visits"], record.Bins["prefs"])
// Touch touchPolicy := as.NewWritePolicy(0, 300) err = client.Touch(touchPolicy, key) if err != nil { log.Fatal(err) }
// Durable delete: // deletePolicy := as.NewWritePolicy(0, 0) // deletePolicy.DurableDelete = true // _, err = client.Delete(deletePolicy, key)
removePolicy := as.NewWritePolicy(0, 0) // empty write policy _, err = client.Delete(removePolicy, key) if err != nil { log.Fatal(err) }}#include <stdio.h>#include <aerospike/aerospike.h>#include <aerospike/aerospike_key.h>#include <aerospike/as_policy.h>#include <aerospike/as_record.h>#include <aerospike/as_operations.h>#include <aerospike/as_map_operations.h>
// Assumes `aerospike as` is already initialized and connected.
as_error err;as_key key;as_key_init_str(&key, "test", "demo", "user1");
// Upsertas_hashmap prefs;as_hashmap_init(&prefs, 2);as_stringmap_set_str(&prefs, "theme", "dark");as_stringmap_set_str(&prefs, "lang", "en");
as_record rec;as_record_inita(&rec, 3);as_record_set_str(&rec, "name", "Alice");as_record_set_int64(&rec, "visits", 1);as_record_set_map(&rec, "prefs", (as_map *)&prefs);
aerospike_key_put(&as, &err, NULL, &key, &rec);as_record_destroy(&rec);
// Readas_record *p_rec = NULL;aerospike_key_get(&as, &err, NULL, &key, &p_rec);printf("Record: name=%s visits=%lld\n", as_record_get_str(p_rec, "name"), (long long)as_record_get_int64(p_rec, "visits"));as_record_destroy(p_rec);
// Merge-update (put)as_record upd;as_record_inita(&upd, 1);as_record_set_str(&upd, "name", "Alice K.");aerospike_key_put(&as, &err, NULL, &key, &upd);as_record_destroy(&upd);
// Update (operate)as_operations ops;as_operations_inita(&ops, 4);as_operations_add_incr(&ops, "visits", 1);
as_string lang_key;as_string_init(&lang_key, "lang", false);as_string lang_val;as_string_init(&lang_val, "fr", false);as_operations_map_put(&ops, "prefs", NULL, NULL, (as_val *)&lang_key, (as_val *)&lang_val);
as_operations_add_read(&ops, "visits");as_operations_add_read(&ops, "prefs");
p_rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops, &p_rec);as_operations_destroy(&ops);as_record_destroy(p_rec);
// Touchas_operations touch_ops;as_operations_inita(&touch_ops, 1);as_operations_add_touch(&touch_ops);touch_ops.ttl = 300;
p_rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &touch_ops, &p_rec);as_operations_destroy(&touch_ops);as_record_destroy(p_rec);
// Durable delete:// as_policy_remove deletePolicy;// as_policy_remove_init(&deletePolicy);// deletePolicy.durable_delete = true;// aerospike_key_remove(&as, &err, &deletePolicy, &key);
as_policy_remove removePolicy;as_policy_remove_init(&removePolicy);aerospike_key_remove(&as, &err, &removePolicy, &key);using Aerospike.Client;using System.Collections.Generic;
// ConnectAerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
Key key = new Key("test", "demo", "user1");
// Upsertvar prefs = new Dictionary<string, object> { { "theme", "dark" }, { "lang", "en" }};
client.Put(null, key, new Bin("name", "Alice"), new Bin("visits", 1), new Bin("prefs", prefs));
// ReadRecord record = client.Get(null, key);Console.WriteLine("Record: {0}", record.bins);
// Merge-update (put)client.Put(null, key, new Bin("name", "Alice K."));
// Update (operate)record = client.Operate(null, key, Operation.Add(new Bin("visits", 1)), MapOperation.Put(MapPolicy.Default, "prefs", Value.Get("lang"), Value.Get("fr")), Operation.Get("visits"), Operation.Get("prefs"));
Console.WriteLine("visits: {0}, prefs: {1}", record.GetValue("visits"), record.GetValue("prefs"));
// TouchWritePolicy touchPolicy = new WritePolicy();touchPolicy.expiration = 300;
client.Touch(touchPolicy, key);
// Durable delete:// WritePolicy deletePolicy = new WritePolicy();// deletePolicy.durableDelete = true;// client.Delete(deletePolicy, key);
WritePolicy removePolicy = new WritePolicy(); // empty / defaultclient.Delete(removePolicy, key);
client.Close();const Aerospike = await import("aerospike");const op = Aerospike.operations;const maps = Aerospike.maps;
// Connectconst client = await Aerospike.connect({ hosts: "127.0.0.1:3000" });
const key = new Aerospike.Key("test", "demo", "user1");
// Upsertconst bins = { name: "Alice", visits: 1, prefs: { theme: "dark", lang: "en" },};
await client.put(key, bins);
// Readlet record = await client.get(key);console.info("Record:", record.bins);
// Merge-update (put)await client.put(key, { name: "Alice K." });
// Update (operate)const ops = [ op.incr("visits", 1), maps.put("prefs", "lang", "fr"), op.read("visits"), op.read("prefs"),];
record = await client.operate(key, ops);console.info("visits:", record.bins.visits, "prefs:", record.bins.prefs);
// Touchawait client.operate(key, [op.touch(300)]);
// Durable delete:// const deletePolicy = new Aerospike.WritePolicy({ durableDelete: true });// await client.remove(key, deletePolicy);
const removePolicy = new Aerospike.WritePolicy(); // empty write policyawait client.remove(key, removePolicy);
await client.close();References
See these topics for language-specific examples: