Skip to content

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 bins
session.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:

JavaPythonSelectsExample (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 key
Record rec = session.query(key)
.bin("profile").onMapKey("name").getValues()
.execute()
.getFirstRecord();
// rec.getString("profile") → "Alice"
// Get multiple values by key range
rec = session.query(key)
.bin("inventory").onMapKeyRange("apples", "dates").getValues()
.execute()
.getFirstRecord();
// rec.getList("inventory") → [5, 12] (values for "apples" and "bananas")
// Get key-value pairs
rec = session.query(key)
.bin("inventory").onMapKeyRange("apples", "dates").getKeysAndValues()
.execute()
.getFirstRecord();
// Returns list of [key, value, key, value, ...]
// Count entries in a range
rec = 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 end
session.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 update
session.update(key)
.bin("inventory").onMapKey("apples").upsert(15)
.execute();
// Increment a numeric value
session.update(key)
.bin("inventory").onMapKey("apples").add(5)
.execute();
// Bulk upsert multiple entries
session.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 options
session.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 entry
session.update(key)
.bin("inventory").onMapKey("dates").remove()
.execute();
// Remove a range and return the removed values
session.update(key)
.bin("inventory").onMapValueRange(1L, 5L).removeAnd().getValues()
.execute();
// Remove everything EXCEPT the selected range
session.update(key)
.bin("inventory").onMapKeyRange("apples", "dates").removeAllOthers()
.execute();
// Clear the entire map
session.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 size
Record rec = session.query(key)
.bin("inventory").mapSize()
.execute()
.getFirstRecord();
// rec.getLong("inventory") → 4
// Check if a key exists
rec = 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

JavaPythonSelectsExample (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 index
Record rec = session.query(key)
.bin("scores").onListIndex(0).getValues()
.execute()
.getFirstRecord();
// rec.getLong("scores") → 85
// Get by index using the direct method
rec = session.query(key)
.bin("scores").listGet(2)
.execute()
.getFirstRecord();
// rec.getLong("scores") → 78
// Get a range of elements
rec = session.query(key)
.bin("scores").listGetRange(1, 3)
.execute()
.getFirstRecord();
// rec.getList("scores") → [92, 78, 95]
// Count elements in a value range
rec = session.query(key)
.bin("scores").onListValueRange(80L, 90L).count()
.execute()
.getFirstRecord();
// rec.getLong("scores") → 2 (85 and 88)
// List size
rec = 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 list
session.update(key)
.bin("scores").listAppend(99)
.execute();
// Insert at a specific index
session.update(key)
.bin("scores").listInsert(0, 100)
.execute();
// Overwrite an element at an index
session.update(key)
.bin("scores").listSet(2, 80)
.execute();
// Increment a numeric element at an index
session.update(key)
.bin("scores").listIncrement(0, 5)
.execute();
// Append multiple items
session.update(key)
.bin("scores").listAppendItems(List.of(60, 70))
.execute();
// Insert multiple items at an index
session.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 index
session.update(key)
.bin("scores").listRemove(0)
.execute();
// Remove a range
session.update(key)
.bin("scores").listRemoveRange(0, 2)
.execute();
// Pop (remove and return) by index
Record 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 clear
session.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 data
session.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 map
Record rec = session.query(key)
.bin("data").onMapKey("users").listSize()
.execute()
.getFirstRecord();
// rec.getLong("data") → 3
// Read: get a single list element inside a map
rec = session.query(key)
.bin("data").onMapKey("users").listGet(1)
.execute()
.getFirstRecord();
// rec.getString("data") → "Bob"
// Read: get a range from a nested list
rec = session.query(key)
.bin("data").onMapKey("counts").listGetRange(0, 2)
.execute()
.getFirstRecord();
// rec.getList("data") → [10, 20]
// Write: append to a nested list
session.update(key)
.bin("data").onMapKey("users").listAppend("Diana")
.execute();
// Write: insert at index in a nested list
session.update(key)
.bin("data").onMapKey("users").listInsert(0, "Zara")
.execute();
// Write: increment a value in a nested list
session.update(key)
.bin("data").onMapKey("counts").listIncrement(0, 5)
.execute();
// Write: upsert into a nested map
session.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()

Feedback

Was this page helpful?

What type of feedback are you giving?

What would you like us to know?

+Capture screenshot

Can we reach out to you?