Map operations
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
A map bin stores key-value pairs. Keys are strings, integers, or byte arrays, and values can be any supported data type. The server’s map collection data type (CDT) operations change, read, and remove individual entries in a single round trip, without the client reading the whole bin first.
Client::put always replaces the full bin value. To change entries of a map bin that already exists, use the aerospike::operations::maps builders with Client::operate().
Setup
use aerospike::operations::maps;use aerospike::{ as_bin, as_key, as_map, as_val, Bins, Client, ClientPolicy, MapPolicy, MapReturnType, ReadPolicy, Value, WritePolicy,};
let client = Client::new(&ClientPolicy::default(), &"127.0.0.1:3000").await?;let policy = MapPolicy::default();📖 API reference:
Client::new|operations::maps|MapPolicy
The as_map! and as_list! macros expand to as_val!, so import as_val too.
Write a map bin
To write a map as the whole value of a bin, build it with as_map! and pass it to put():
let key = as_key!("test", "stats", "page:1");let bin = as_bin!("daily", as_map!("2026-10-01" => 5));client.put(&WritePolicy::default(), &key, &[bin]).await?;📖 API reference:
as_map!|Value::HashMap
Increment counters in a map
maps::increment_value(&policy, bin, key, amount) adds amount to the number stored under key. If the key doesn’t exist yet, the server creates it and sets it to amount. No read is required first.
Pass several increments in one operate() call to change several keys in a single round trip. record.results holds one answer per operation, in order. Each answer is the key’s new value:
let key = as_key!("test", "stats", "page:1");let ops = vec![ maps::increment_value(&policy, "daily", Value::from("2026-10-01"), Value::from(1)), maps::increment_value(&policy, "daily", Value::from("2026-10-02"), Value::from(1)),];let record = client.operate(&WritePolicy::default(), &key, &ops).await?;println!("{:?}", record.results);📖 API reference:
operations::maps::increment_value|Client::operate
Read a map back
A get returns a map bin as a Value::OrderedMap, which holds the entries in key order. Match on it to read the entries. Key-ordered maps (K-ordered on the server) arrive as Value::SortedMap instead:
let record = client.get(&ReadPolicy::default(), &key, Bins::All).await?;if let Some(Value::OrderedMap(daily)) = record.bins.get("daily") { for (date, views) in daily { println!("{date}: {views}"); }}📖 API reference:
Value::OrderedMap
Select entries by rank
The rank of an entry is its position when the server sorts the entries by value. Rank 0 is the entry with the lowest value. A negative rank counts from the highest value, so -1 is the highest.
maps::get_by_rank_range(bin, rank, count, return_type) selects count entries that start at rank. To read the three highest-scoring players of a leaderboard, start at rank -3:
let key = as_key!("test", "games", "board:1");let scores = as_map!("ann" => 120, "bob" => 340, "cat" => 90, "dan" => 500, "eve" => 275);client.put(&WritePolicy::default(), &key, &[as_bin!("scores", scores)]).await?;
let ops = vec![maps::get_by_rank_range("scores", -3, 3, MapReturnType::KeyValue)];let record = client.operate(&WritePolicy::default(), &key, &ops).await?;
// The entries come back from the lowest of the three scores to the highest.if let Some(Value::KeyValueList(entries)) = record.operation_result(0) { for (player, score) in entries.iter().rev() { println!("{player}: {score}"); }}📖 API reference:
operations::maps::get_by_rank_range|Value::KeyValueList
MapReturnType::KeyValue returns the selected entries as a Value::KeyValueList, a list of (key, value) pairs in rank order. The server selects the entries, so the program doesn’t fetch and sort the whole map.
Remove a key and return its value
maps::remove_by_key(bin, key, return_type) removes one entry from the map. The return type selects what the server sends back about the removed entry. To remove a key and get its value in the same call, use MapReturnType::Value:
let key = as_key!("test", "settings", "user:1");let prefs = as_map!("lang" => "en", "theme" => "dark", "beta" => true);client.put(&WritePolicy::default(), &key, &[as_bin!("prefs", prefs)]).await?;
let ops = vec![maps::remove_by_key("prefs", Value::from("beta"), MapReturnType::Value)];let record = client.operate(&WritePolicy::default(), &key, &ops).await?;println!("removed: {:?}", record.operation_result(0));📖 API reference:
operations::maps::remove_by_key
The other entries of the map stay as they were. The server updates the entry in place, and the client sends one map operation instead of reading and writing the whole bin.
Choose what an operation returns
Map read and remove operations take a MapReturnType that selects what the server returns for the entries the operation selected:
MapReturnType | What the server returns |
|---|---|
None | Nothing. The result is Value::Nil. |
Count | The number of entries selected. |
Key | The key of a single entry, or a list of keys for a range. |
Value | The value of a single entry, or a list of values for a range. |
KeyValue | The entries as key-value pairs. |
Index | The key-order position of the entry, where 0 is the first key. |
ReverseIndex | The position in reverse key order, where 0 is the last key. |
Rank | The rank of the entry, where 0 is the lowest value. |
ReverseRank | The rank in reverse value order, where 0 is the highest value. |
Exists | true if the operation selected at least one entry. |
📖 API reference:
MapReturnType
To invert a selection, pass InvertedMapReturn(MapReturnType::Key) from aerospike::operations::maps instead of the plain return type.
For nested-path navigation with CdtContext, see the operations::maps API reference.
Next steps
- List operations: Change, read, and remove list elements on the server.
- Bin operations: Combine several operations in one
operate()call.