CDT Operations

Complex Data Type (CDT) operations let you read and modify nested lists and maps within a single bin, server-side, without fetching the whole record.

Reading CDT Data

Navigate into a bin’s structure using on_list() and on_map_key():

users = DataSet.of("test", "users")

# Read a map value by key
stream = await (
    session.query(users.id(1))
    .bin("settings").on_map_key("theme").get()
    .execute()
)

# Read a list element by index
stream = await (
    session.query(users.id(1))
    .bin("scores").on_list_index(0).get()
    .execute()
)

# Read a nested value: $.profile.address.city
stream = await (
    session.query(users.id(1))
    .bin("profile").on_map_key("address").on_map_key("city").get()
    .execute()
)

List Ranges

# Get items by index range
stream = await (
    session.query(users.id(1))
    .bin("scores").on_list_index_range(0, 3).get()
    .execute()
)

# Get items by value range
stream = await (
    session.query(users.id(1))
    .bin("scores").on_list_value_range(10, 100).get()
    .execute()
)

Map Ranges

# Get map entries by key range
stream = await (
    session.query(users.id(1))
    .bin("metrics").on_map_key_range("a", "m").get()
    .execute()
)

# Get by rank (top N values)
stream = await (
    session.query(users.id(1))
    .bin("scores").on_map_value_rank_range(-3).get()
    .execute()
)

Collection Metadata

# Get list size
stream = await (
    session.query(users.id(1))
    .bin("scores").on_list().size()
    .execute()
)

# Check if key exists in map
stream = await (
    session.query(users.id(1))
    .bin("settings").on_map_key("theme").exists()
    .execute()
)

Writing CDT Data

Set a Value

# Set a map key
await (
    session.update(users.id(1))
    .bin("settings").on_map_key("theme").set_to("dark")
    .execute()
)

# Set a list element by index
await (
    session.update(users.id(1))
    .bin("scores").on_list_index(0).set_to(99)
    .execute()
)

Add / Increment

# Increment a map value
await (
    session.update(users.id(1))
    .bin("counters").on_map_key("views").add(1)
    .execute()
)

List Operations

# Append to a list
await (
    session.update(users.id(1))
    .bin("scores").list_append(95)
    .execute()
)

# Add item (insert-sorted for ordered lists)
await (
    session.update(users.id(1))
    .bin("scores").list_add(95)
    .execute()
)

# Append multiple items
await (
    session.update(users.id(1))
    .bin("tags").list_append_items(["python", "aerospike"])
    .execute()
)

# Clear a list
await (
    session.update(users.id(1))
    .bin("scores").list_clear()
    .execute()
)

# Sort a list
await (
    session.update(users.id(1))
    .bin("scores").list_sort()
    .execute()
)

Map Operations

# Upsert map entries
await (
    session.update(users.id(1))
    .bin("settings").map_upsert_items({"theme": "dark", "lang": "en"})
    .execute()
)

# Clear a map
await (
    session.update(users.id(1))
    .bin("settings").map_clear()
    .execute()
)

Remove

# Remove a map key
await (
    session.update(users.id(1))
    .bin("settings").on_map_key("deprecated_key").remove()
    .execute()
)

# Remove a list element
await (
    session.update(users.id(1))
    .bin("scores").on_list_index(-1).remove()
    .execute()
)

Nested Navigation

CDT navigation composes — navigate into arbitrarily nested structures:

# $.users_map["alice"].scores[0] = 100
await (
    session.update(dataset.id(1))
    .bin("users_map").on_map_key("alice").on_map_key("scores").on_list_index(0).set_to(100)
    .execute()
)

AEL expressions on CDT

AEL supports CDT paths for filtering:

# Filter records where the list has more than 5 items
stream = await (
    session.query(users)
    .where("$.scores.count() > 5")
    .execute()
)

# Filter on a nested map value
stream = await (
    session.query(users)
    .where('$.settings.["theme"] == "dark"')
    .execute()
)