CDT (Collection data type) operations
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Aerospike bins can hold maps and lists. CDT operations let you read, write, and remove elements within these structures in a single server call, with no read-modify-write needed.
Setup (used in all examples below)
DataSet users = DataSet.of("test", "users");Key key = users.id("user-1");
// Store a record with map and list binssession.upsert(key) .bin("profile").setTo(Map.of( "name", "Alice", "age", 30, "email", "alice@example.com" )) .bin("scores").setTo(List.of(85, 92, 78, 95, 88)) .bin("inventory").setTo(Map.of( "apples", 5, "bananas", 12, "dates", 3, "figs", 8 )) .execute();📖 API reference:
DataSet.of(...)|DataSet.id(...)|Key|Session.upsert(DataSet)|Session.upsert(Key)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|BinBuilder.setTo(Map)|BinBuilder.setTo(List)|ChainableQueryBuilder.execute()
from aerospike_sdk import Behavior, DataSet, SpecialValue
async def setup(session): users = DataSet.of("test", "users") key = users.id("user-1")
await ( session.upsert(key) .put({ "profile": {"name": "Alice", "age": 30, "email": "alice@example.com"}, "scores": [85, 92, 78, 95, 88], "inventory": {"apples": 5, "bananas": 12, "dates": 3, "figs": 8}, }) .execute() )📖 API reference:
DataSet.of()|DataSet.id()|Session.upsert()|WriteSegmentBuilder.put()|WriteSegmentBuilder.execute()
Map Operations
Selecting elements
Start with .bin("name") then chain a selector to pick which map entries to operate on:
| Java | Python | Selects | Example (Java / Python) |
|---|---|---|---|
onMapKey(key) | on_map_key(key) | Single entry by key | .onMapKey("name") / .on_map_key("name") |
onMapKeyRange(start, end) | on_map_key_range(start, end) | Range of keys [start, end) | .onMapKeyRange("a", "d") / .on_map_key_range("a", "d") |
onMapKeyList(keys) | on_map_key_list(keys) | Multiple specific keys | .onMapKeyList(List.of("name","age")) / .on_map_key_list(["name", "age"]) |
onMapIndex(i) | on_map_index(i) | Entry at sorted position i | .onMapIndex(0) / .on_map_index(0) |
onMapIndexRange(i, count) | on_map_index_range(i, count) | count entries from position i | .onMapIndexRange(0, 3) / .on_map_index_range(0, 3) |
onMapValue(val) | on_map_value(val) | Entries with this value | .onMapValue(30) / .on_map_value(30) |
onMapValueRange(start, end) | on_map_value_range(start, end) | Values in [start, end) | .onMapValueRange(1, 10) / .on_map_value_range(1, 10) |
onMapRank(r) | on_map_rank(r) | Entry at rank r (by value) | .onMapRank(-1) / .on_map_rank(-1) |
onMapRankRange(r, count) | on_map_rank_range(r, count) | count entries from rank r | .onMapRankRange(0, 3) / .on_map_rank_range(0, 3) |
Reading from maps
// Get a single value by keyRecord rec = session.query(key) .bin("profile").onMapKey("name").getValues() .execute() .getFirstRecord();// rec.getString("profile") → "Alice"
// Get multiple values by key rangerec = session.query(key) .bin("inventory").onMapKeyRange("apples", "dates").getValues() .execute() .getFirstRecord();// rec.getList("inventory") → [5, 12] (values for "apples" and "bananas")
// Get key-value pairsrec = session.query(key) .bin("inventory").onMapKeyRange("apples", "dates").getKeysAndValues() .execute() .getFirstRecord();// Returns list of [key, value, key, value, ...]
// Count entries in a rangerec = session.query(key) .bin("inventory").onMapValueRange(1L, 10L).count() .execute() .getFirstRecord();// rec.getLong("inventory") → 3 (apples=5, dates=3, figs=8)📖 API reference:
Session.query(Key)|Session.query(DataSet)|ChainableQueryBuilder.bin(...)|BinBuilder.onMapKey(...)|BinBuilder.onMapKeyRange(...)|CdtReadOnlyBuilder.getValues()|CdtReadOnlyBuilder.getKeysAndValues()|CdtReadOnlyBuilder.count()|ChainableQueryBuilder.execute()|RecordStream.getFirstRecord()|Record.getString(...)|Record.getLong(...)|Record.getList(...)
async def read_from_maps(session, key): # Get a single value by key stream = await ( session.query(key) .bin("profile").on_map_key("name").get_values() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("profile") → "Alice" stream.close()
# Get multiple values by key range stream = await ( session.query(key) .bin("inventory").on_map_key_range("apples", "dates").get_values() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("inventory") → [5, 12] (values for "apples" and "bananas") stream.close()
# Get key-value pairs stream = await ( session.query(key) .bin("inventory").on_map_key_range("apples", "dates").get_keys_and_values() .execute() ) first = await stream.first_or_raise() # Returns list of [key, value, key, value, ...] stream.close()
# Count entries in a range stream = await ( session.query(key) .bin("inventory").on_map_value_range(1, 10).count() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("inventory") → 3 (apples=5, dates=3, figs=8) stream.close()📖 API reference:
Session.query()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|QueryBuilder.execute()
Boundary values with SpecialValue
Use SpecialValue.INFINITY and SpecialValue.NULL for open-ended ranges:
// All keys from "c" to the endsession.query(key) .bin("inventory").onMapKeyRange("c", SpecialValue.INFINITY).getValues() .execute();
// All keys from the beginning to "c"session.query(key) .bin("inventory").onMapKeyRange(SpecialValue.NULL, "c").getValues() .execute();📖 API reference:
Session.query(Key)|Session.query(DataSet)|ChainableQueryBuilder.bin(...)|BinBuilder.onMapKeyRange(...)|CdtReadOnlyBuilder.getValues()|ChainableQueryBuilder.execute()
from aerospike_sdk import SpecialValue
async def map_key_range_with_special_values(session, key): # All keys from "c" to the end stream = await ( session.query(key) .bin("inventory").on_map_key_range("c", SpecialValue.INFINITY).get_values() .execute() ) await stream.first_or_raise() stream.close()
# All keys from the beginning to "c" stream = await ( session.query(key) .bin("inventory").on_map_key_range(SpecialValue.NULL, "c").get_values() .execute() ) await stream.first_or_raise() stream.close()📖 API reference:
Session.query()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|QueryBuilder.execute()
Writing to maps
// Insert a new entry (fails if key already exists)session.update(key) .bin("inventory").onMapKey("grapes").insert(20) .execute();
// Update an existing entry (fails if key doesn't exist)session.update(key) .bin("inventory").onMapKey("apples").update(10) .execute();
// Upsert — insert or updatesession.update(key) .bin("inventory").onMapKey("apples").upsert(15) .execute();
// Increment a numeric valuesession.update(key) .bin("inventory").onMapKey("apples").add(5) .execute();
// Bulk upsert multiple entriessession.update(key) .bin("inventory").mapUpsertItems(Map.of("kiwi", 7, "mango", 4)) .execute();📖 API reference:
Session.update(DataSet)|Session.update(Key)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|BinBuilder.onMapKey(...)|BinBuilder.add(...)|ChainableQueryBuilder.execute()
async def write_to_maps(session, key): # Insert a new entry (fails if key already exists) await ( session.update(key) .bin("inventory").on_map_key("grapes").insert(20) .execute() )
# Update an existing entry (fails if key doesn't exist) await ( session.update(key) .bin("inventory").on_map_key("apples").update(10) .execute() )
# Upsert — insert or update await ( session.update(key) .bin("inventory").on_map_key("apples").upsert(15) .execute() )
# Increment a numeric value await ( session.update(key) .bin("inventory").on_map_key("apples").add(5) .execute() )
# Bulk upsert multiple entries await ( session.update(key) .bin("inventory").map_upsert_items({"kiwi": 7, "mango": 4}) .execute() )📖 API reference:
Session.update()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|WriteSegmentBuilder.execute()
Write options
// Insert with map ordering and persistence optionssession.update(key) .bin("inventory").onMapKey("pears").insert(6, opt -> opt .mapOrder(MapOrder.KEY_VALUE_ORDERED) .persistIndex()) .execute();📖 API reference:
Session.update(DataSet)|Session.update(Key)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|BinBuilder.onMapKey(...)|ChainableQueryBuilder.execute()
async def map_write_options_note(session, key): # MapOrder and persistIndex write options are not exposed on the Python CDT builder. # Insert without ordering/persistence options: await ( session.update(key) .bin("inventory").on_map_key("pears").insert(6) .execute() )📖 API reference:
Session.update()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|WriteSegmentBuilder.execute()
Removing from maps
// Remove a single entrysession.update(key) .bin("inventory").onMapKey("dates").remove() .execute();
// Remove a range and return the removed valuessession.update(key) .bin("inventory").onMapValueRange(1L, 5L).removeAnd().getValues() .execute();
// Remove everything EXCEPT the selected rangesession.update(key) .bin("inventory").onMapKeyRange("apples", "dates").removeAllOthers() .execute();
// Clear the entire mapsession.update(key) .bin("inventory").mapClear() .execute();📖 API reference:
Session.update(DataSet)|Session.update(Key)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|BinBuilder.onMapKey(...)|BinBuilder.onMapKeyRange(...)|BinBuilder.remove()|CdtReadOnlyBuilder.getValues()|ChainableQueryBuilder.execute()
async def remove_from_maps(session, key): # Remove a single entry await ( session.update(key) .bin("inventory").on_map_key("dates").remove() .execute() )
# Remove a range and return the removed values from aerospike_sdk import MapReturnType await ( session.update(key) .bin("inventory").on_map_value_range(1, 5) .remove(return_type=MapReturnType.VALUE) .execute() )
# Remove everything EXCEPT the selected range await ( session.update(key) .bin("inventory").on_map_key_range("apples", "dates").remove_all_others() .execute() )
# Clear the entire map await ( session.update(key) .bin("inventory").map_clear() .execute() )📖 API reference:
Session.update()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|WriteSegmentBuilder.execute()
Other map queries
// Map sizeRecord rec = session.query(key) .bin("inventory").mapSize() .execute() .getFirstRecord();// rec.getLong("inventory") → 4
// Check if a key existsrec = session.query(key) .bin("inventory").onMapKey("apples").exists() .execute() .getFirstRecord();// rec.getBoolean("inventory") → true📖 API reference:
Session.query(Key)|Session.query(DataSet)|ChainableQueryBuilder.bin(...)|BinBuilder.onMapKey(...)|ChainableQueryBuilder.execute()|RecordStream.getFirstRecord()|Record.getLong(...)
async def other_map_queries(session, key): # Map size stream = await ( session.query(key) .bin("inventory").map_size() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("inventory") → 4 stream.close()
# Check if a key exists stream = await ( session.query(key) .bin("inventory").on_map_key("apples").exists() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("inventory") → True stream.close()📖 API reference:
Session.query()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|QueryBuilder.execute()
List Operations
Selecting elements
| Java | Python | Selects | Example (Java / Python) |
|---|---|---|---|
onListIndex(i) | on_list_index(i) | Single element at position i | .onListIndex(0) / .on_list_index(0) |
onListIndexRange(i, count) | on_list_index_range(i, count) | count elements from position i | .onListIndexRange(0, 3) / .on_list_index_range(0, 3) |
onListIndexRange(i) | on_list_index_range(i) | All elements from position i to end | .onListIndexRange(2) / .on_list_index_range(2) |
onListValue(val) | on_list_value(val) | Elements equal to val | .onListValue(85) / .on_list_value(85) |
onListValueRange(start, end) | on_list_value_range(start, end) | Values in [start, end) | .onListValueRange(80, 90) / .on_list_value_range(80, 90) |
onListValueList(vals) | on_list_value_list(vals) | Elements matching any value in list | .onListValueList(List.of(85, 95)) / .on_list_value_list([85, 95]) |
onListRank(r) | on_list_rank(r) | Element at rank r (by value) | .onListRank(-1) / .on_list_rank(-1) |
onListRankRange(r, count) | on_list_rank_range(r, count) | count elements from rank r | .onListRankRange(0, 3) / .on_list_rank_range(0, 3) |
Reading from lists
// Get a single element by indexRecord rec = session.query(key) .bin("scores").onListIndex(0).getValues() .execute() .getFirstRecord();// rec.getLong("scores") → 85
// Get by index using the direct methodrec = session.query(key) .bin("scores").listGet(2) .execute() .getFirstRecord();// rec.getLong("scores") → 78
// Get a range of elementsrec = session.query(key) .bin("scores").listGetRange(1, 3) .execute() .getFirstRecord();// rec.getList("scores") → [92, 78, 95]
// Count elements in a value rangerec = session.query(key) .bin("scores").onListValueRange(80L, 90L).count() .execute() .getFirstRecord();// rec.getLong("scores") → 2 (85 and 88)
// List sizerec = session.query(key) .bin("scores").listSize() .execute() .getFirstRecord();// rec.getLong("scores") → 5
// Get the highest value (rank -1)rec = session.query(key) .bin("scores").onListRank(-1).getValues() .execute() .getFirstRecord();// rec.getLong("scores") → 95📖 API reference:
Session.query(Key)|Session.query(DataSet)|ChainableQueryBuilder.bin(...)|CdtReadOnlyBuilder.getValues()|CdtReadOnlyBuilder.count()|ChainableQueryBuilder.execute()|RecordStream.getFirstRecord()|Record.getLong(...)|Record.getList(...)
async def read_from_lists(session, key): # Get a single element by index stream = await ( session.query(key) .bin("scores").on_list_index(0).get_values() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("scores") → 85 stream.close()
# Get by index using the direct method stream = await ( session.query(key) .bin("scores").list_get(2) .execute() ) first = await stream.first_or_raise() # first.record.bins.get("scores") → 78 stream.close()
# Get a range of elements stream = await ( session.query(key) .bin("scores").list_get_range(1, 3) .execute() ) first = await stream.first_or_raise() # first.record.bins.get("scores") → [92, 78, 95] stream.close()
# Count elements in a value range stream = await ( session.query(key) .bin("scores").on_list_value_range(80, 90).count() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("scores") → 2 (85 and 88) stream.close()
# List size stream = await ( session.query(key) .bin("scores").list_size() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("scores") → 5 stream.close()
# Get the highest value (rank -1) stream = await ( session.query(key) .bin("scores").on_list_rank(-1).get_values() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("scores") → 95 stream.close()📖 API reference:
Session.query()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|QueryBuilder.execute()
Writing to lists
// Append to an unordered listsession.update(key) .bin("scores").listAppend(99) .execute();
// Insert at a specific indexsession.update(key) .bin("scores").listInsert(0, 100) .execute();
// Overwrite an element at an indexsession.update(key) .bin("scores").listSet(2, 80) .execute();
// Increment a numeric element at an indexsession.update(key) .bin("scores").listIncrement(0, 5) .execute();
// Append multiple itemssession.update(key) .bin("scores").listAppendItems(List.of(60, 70)) .execute();
// Insert multiple items at an indexsession.update(key) .bin("scores").listInsertItems(1, List.of(91, 93)) .execute();
// Add to an ordered list (maintains sort order)session.update(key) .bin("scores").listAdd(87) .execute();📖 API reference:
Session.update(DataSet)|Session.update(Key)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|ChainableQueryBuilder.execute()
async def write_to_lists(session, key): # Append to an unordered list await ( session.update(key) .bin("scores").list_append(99) .execute() )
# Insert at a specific index await ( session.update(key) .bin("scores").list_insert(0, 100) .execute() )
# Overwrite an element at an index await ( session.update(key) .bin("scores").list_set(2, 80) .execute() )
# Increment a numeric element at an index await ( session.update(key) .bin("scores").list_increment(0, 5) .execute() )
# Append multiple items await ( session.update(key) .bin("scores").list_append_items([60, 70]) .execute() )
# Insert multiple items at an index await ( session.update(key) .bin("scores").list_insert_items(1, [91, 93]) .execute() )
# Add to an ordered list (maintains sort order) await ( session.update(key) .bin("scores").list_add(87) .execute() )📖 API reference:
Session.update()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|WriteSegmentBuilder.execute()
Removing from lists
// Remove by indexsession.update(key) .bin("scores").listRemove(0) .execute();
// Remove a rangesession.update(key) .bin("scores").listRemoveRange(0, 2) .execute();
// Pop (remove and return) by indexRecord rec = session.update(key) .bin("scores").listPop(0) .execute() .getFirstRecord();// rec.getLong("scores") → the removed value
// Remove by value range (using selectors)session.update(key) .bin("scores").onListValueRange(80L, 90L).remove() .execute();
// Trim: keep only elements at [index, index+count)session.update(key) .bin("scores").listTrim(0, 3) .execute();
// Sort, then clearsession.update(key) .bin("scores").listSort() .execute();
session.update(key) .bin("scores").listClear() .execute();📖 API reference:
Session.update(DataSet)|Session.update(Key)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|BinBuilder.remove()|ChainableQueryBuilder.execute()|RecordStream.getFirstRecord()|Record.getLong(...)
async def remove_from_lists(session, key): # Remove by index await ( session.update(key) .bin("scores").list_remove(0) .execute() )
# Remove a range await ( session.update(key) .bin("scores").list_remove_range(0, 2) .execute() )
# Pop (remove and return) by index stream = await ( session.update(key) .bin("scores").list_pop(0) .execute() ) first = await stream.first_or_raise() # first.record.bins.get("scores") → the removed value stream.close()
# Remove by value range (using selectors) await ( session.update(key) .bin("scores").on_list_value_range(80, 90).remove() .execute() )
# Trim: keep only elements at [index, index+count) await ( session.update(key) .bin("scores").list_trim(0, 3) .execute() )
# Sort, then clear await ( session.update(key) .bin("scores").list_sort() .execute() )
await ( session.update(key) .bin("scores").list_clear() .execute() )📖 API reference:
Session.update()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|WriteSegmentBuilder.execute()
Nested CDT Operations
Chain context methods to navigate into nested structures. Each onMapKey/onListIndex pushes deeper into the path before the terminal operation.
// Setup: nested datasession.upsert(key) .bin("data").setTo(Map.of( "users", List.of("Alice", "Bob", "Charlie"), "meta", Map.of("version", 1, "active", true), "counts", List.of(10, 20, 30) )) .execute();
// Read: get list size inside a mapRecord rec = session.query(key) .bin("data").onMapKey("users").listSize() .execute() .getFirstRecord();// rec.getLong("data") → 3
// Read: get a single list element inside a maprec = session.query(key) .bin("data").onMapKey("users").listGet(1) .execute() .getFirstRecord();// rec.getString("data") → "Bob"
// Read: get a range from a nested listrec = session.query(key) .bin("data").onMapKey("counts").listGetRange(0, 2) .execute() .getFirstRecord();// rec.getList("data") → [10, 20]
// Write: append to a nested listsession.update(key) .bin("data").onMapKey("users").listAppend("Diana") .execute();
// Write: insert at index in a nested listsession.update(key) .bin("data").onMapKey("users").listInsert(0, "Zara") .execute();
// Write: increment a value in a nested listsession.update(key) .bin("data").onMapKey("counts").listIncrement(0, 5) .execute();
// Write: upsert into a nested mapsession.update(key) .bin("data").onMapKey("meta").mapUpsertItems(Map.of("region", "us-east")) .execute();📖 API reference:
Session.upsert(DataSet)|Session.upsert(Key)|Session.update(DataSet)|Session.update(Key)|Session.query(Key)|Session.query(DataSet)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|BinBuilder.setTo(Map)|BinBuilder.onMapKey(...)|ChainableQueryBuilder.execute()|RecordStream.getFirstRecord()|Record.getString(...)|Record.getLong(...)|Record.getList(...)
async def nested_cdt_examples(session, key): # Setup: nested data await ( session.upsert(key) .put({ "data": { "users": ["Alice", "Bob", "Charlie"], "meta": {"version": 1, "active": True}, "counts": [10, 20, 30], }, }) .execute() )
# Read: get list size inside a map stream = await ( session.query(key) .bin("data").on_map_key("users").list_size() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("data") → 3 stream.close()
# Read: get a single list element inside a map stream = await ( session.query(key) .bin("data").on_map_key("users").list_get(1) .execute() ) first = await stream.first_or_raise() # first.record.bins.get("data") → "Bob" stream.close()
# Read: get a range from a nested list stream = await ( session.query(key) .bin("data").on_map_key("counts").list_get_range(0, 2) .execute() ) first = await stream.first_or_raise() # first.record.bins.get("data") → [10, 20] stream.close()
# Write: append to a nested list await ( session.update(key) .bin("data").on_map_key("users").list_append("Diana") .execute() )
# Write: insert at index in a nested list await ( session.update(key) .bin("data").on_map_key("users").list_insert(0, "Zara") .execute() )
# Write: increment a value in a nested list await ( session.update(key) .bin("data").on_map_key("counts").list_increment(0, 5) .execute() )
# Write: upsert into a nested map await ( session.update(key) .bin("data").on_map_key("meta").map_upsert_items({"region": "us-east"}) .execute() )📖 API reference:
Session.query()|Session.upsert()|Session.update()|QueryBuilder.bin()|WriteSegmentBuilder.put()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|QueryBuilder.execute()|WriteSegmentBuilder.execute()
Deep nesting (3+ levels)
session.upsert(key) .bin("org").setTo(Map.of( "dept1", Map.of("members", List.of("Alice", "Bob", "Charlie")) )) .execute();
Record rec = session.query(key) .bin("org").onMapKey("dept1").onMapKey("members").listGet(0) .execute() .getFirstRecord();// rec.getString("org") → "Alice"
rec = session.query(key) .bin("org").onMapKey("dept1").onMapKey("members").listSize() .execute() .getFirstRecord();// rec.getLong("org") → 3📖 API reference:
Session.upsert(DataSet)|Session.upsert(Key)|Session.query(Key)|Session.query(DataSet)|ChainableOperationBuilder.bin(...)|ChainableQueryBuilder.bin(...)|BinBuilder.setTo(Map)|BinBuilder.onMapKey(...)|ChainableQueryBuilder.execute()|RecordStream.getFirstRecord()|Record.getString(...)|Record.getLong(...)
async def deep_nesting_example(session, key): await ( session.upsert(key) .put({ "org": { "dept1": { "members": ["Alice", "Bob", "Charlie"], }, }, }) .execute() )
stream = await ( session.query(key) .bin("org").on_map_key("dept1").on_map_key("members").list_get(0) .execute() ) first = await stream.first_or_raise() # first.record.bins.get("org") → "Alice" stream.close()
stream = await ( session.query(key) .bin("org").on_map_key("dept1").on_map_key("members").list_size() .execute() ) first = await stream.first_or_raise() # first.record.bins.get("org") → 3 stream.close()📖 API reference:
Session.query()|Session.upsert()|QueryBuilder.bin()|WriteSegmentBuilder.put()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|QueryBuilder.execute()|WriteSegmentBuilder.execute()
Multiple CDT operations in one call
Operate on multiple bins in a single server round-trip:
Record rec = session.query(key) .bin("scores").listSize() .bin("inventory").mapSize() .bin("profile").onMapKey("name").getValues() .execute() .getFirstRecord();
long scoreCount = rec.getLong("scores");long itemCount = rec.getLong("inventory");String name = rec.getString("profile");📖 API reference:
Session.query(Key)|Session.query(DataSet)|ChainableQueryBuilder.bin(...)|BinBuilder.onMapKey(...)|CdtReadOnlyBuilder.getValues()|ChainableQueryBuilder.execute()|RecordStream.getFirstRecord()|Record.getString(...)|Record.getLong(...)
async def multiple_cdt_in_one_call(session, key): stream = await ( session.query(key) .bin("scores").list_size() .bin("inventory").map_size() .bin("profile").on_map_key("name").get_values() .execute() ) first = await stream.first_or_raise() bins = first.record.bins
score_count = bins.get("scores") item_count = bins.get("inventory") name = bins.get("profile") stream.close()📖 API reference:
Session.query()|QueryBuilder.bin()|WriteSegmentBuilder.bin()|RecordStream.first_or_raise()|RecordStream.close()|QueryBuilder.execute()