---
title: "CDT (Collection data type) operations"
description: "Guide to Aerospike CDT operations: Read, write, and remove Map and List elements using Java and Python SDKs."
---

# CDT (Collection data type) operations

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/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)

```java
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(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/DataSet.html#of%28java.lang.String%2Cjava.lang.String%29) | [`DataSet.id(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/DataSet.html#id%28java.lang.String%29) | [`Key`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Key.html) | [`Session.upsert(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#upsert%28com.aerospike.client.sdk.DataSet%29) | [`Session.upsert(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#upsert%28com.aerospike.client.sdk.Key%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.setTo(Map)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#setTo%28java.util.Map%29) | [`BinBuilder.setTo(List)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#setTo%28java.util.List%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/dataset.html#aerospike%5Fsdk.dataset.DataSet.of) | [`DataSet.id()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/dataset.html#aerospike%5Fsdk.dataset.DataSet.id) | [`Session.upsert()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.upsert) | [`WriteSegmentBuilder.put()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.put) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.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

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.Key%29) | [`Session.query(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.DataSet%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`BinBuilder.onMapKeyRange(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%2Cjava.lang.String%29) | [`CdtReadOnlyBuilder.getValues()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#getValues%28%29) | [`CdtReadOnlyBuilder.getKeysAndValues()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#getKeysAndValues%28%29) | [`CdtReadOnlyBuilder.count()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#count%28%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29) | [`RecordStream.getFirstRecord()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/RecordStream.html#getFirstRecord%28%29) | [`Record.getString(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getString%28java.lang.String%29) | [`Record.getLong(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getLong%28java.lang.String%29) | [`Record.getList(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getList%28java.lang.String%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.query) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`QueryBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.execute)

### Boundary values with `SpecialValue`

Use `SpecialValue.INFINITY` and `SpecialValue.NULL` for open-ended ranges:

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.Key%29) | [`Session.query(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.DataSet%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.onMapKeyRange(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%2Cjava.lang.String%29) | [`CdtReadOnlyBuilder.getValues()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#getValues%28%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.query) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`QueryBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.execute)

### Writing to maps

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.DataSet%29) | [`Session.update(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.Key%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`BinBuilder.add(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#add%28int%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.update) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.execute)

### Write options

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.DataSet%29) | [`Session.update(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.Key%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.update) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.execute)

### Removing from maps

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.DataSet%29) | [`Session.update(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.Key%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`BinBuilder.onMapKeyRange(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%2Cjava.lang.String%29) | [`BinBuilder.remove()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#remove%28%29) | [`CdtReadOnlyBuilder.getValues()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#getValues%28%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.update) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.execute)

### Other map queries

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.Key%29) | [`Session.query(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.DataSet%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29) | [`RecordStream.getFirstRecord()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/RecordStream.html#getFirstRecord%28%29) | [`Record.getLong(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getLong%28java.lang.String%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.query) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`QueryBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.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

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.Key%29) | [`Session.query(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.DataSet%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`CdtReadOnlyBuilder.getValues()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#getValues%28%29) | [`CdtReadOnlyBuilder.count()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#count%28%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29) | [`RecordStream.getFirstRecord()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/RecordStream.html#getFirstRecord%28%29) | [`Record.getLong(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getLong%28java.lang.String%29) | [`Record.getList(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getList%28java.lang.String%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.query) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`QueryBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.execute)

### Writing to lists

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.DataSet%29) | [`Session.update(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.Key%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.update) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.execute)

### Removing from lists

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.DataSet%29) | [`Session.update(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.Key%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.remove()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#remove%28%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29) | [`RecordStream.getFirstRecord()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/RecordStream.html#getFirstRecord%28%29) | [`Record.getLong(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getLong%28java.lang.String%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.update) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.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.

```java
// 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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#upsert%28com.aerospike.client.sdk.DataSet%29) | [`Session.upsert(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#upsert%28com.aerospike.client.sdk.Key%29) | [`Session.update(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.DataSet%29) | [`Session.update(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#update%28com.aerospike.client.sdk.Key%29) | [`Session.query(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.Key%29) | [`Session.query(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.DataSet%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.setTo(Map)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#setTo%28java.util.Map%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29) | [`RecordStream.getFirstRecord()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/RecordStream.html#getFirstRecord%28%29) | [`Record.getString(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getString%28java.lang.String%29) | [`Record.getLong(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getLong%28java.lang.String%29) | [`Record.getList(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getList%28java.lang.String%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.query) | [`Session.upsert()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.upsert) | [`Session.update()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.update) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.put()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.put) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`QueryBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.execute) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.execute)

### Deep nesting (3+ levels)

```java
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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#upsert%28com.aerospike.client.sdk.DataSet%29) | [`Session.upsert(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#upsert%28com.aerospike.client.sdk.Key%29) | [`Session.query(Key)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.Key%29) | [`Session.query(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.DataSet%29) | [`ChainableOperationBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableOperationBuilder.html#bin%28java.lang.String%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.setTo(Map)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#setTo%28java.util.Map%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29) | [`RecordStream.getFirstRecord()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/RecordStream.html#getFirstRecord%28%29) | [`Record.getString(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getString%28java.lang.String%29) | [`Record.getLong(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getLong%28java.lang.String%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.query) | [`Session.upsert()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.upsert) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.put()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.put) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`QueryBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.execute) | [`WriteSegmentBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.execute)

---

## Multiple CDT operations in one call

Operate on multiple bins in a single server round-trip:

```java
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)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.Key%29) | [`Session.query(DataSet)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#query%28com.aerospike.client.sdk.DataSet%29) | [`ChainableQueryBuilder.bin(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#bin%28java.lang.String%29) | [`BinBuilder.onMapKey(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/BinBuilder.html#onMapKey%28java.lang.String%29) | [`CdtReadOnlyBuilder.getValues()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/CdtReadOnlyBuilder.html#getValues%28%29) | [`ChainableQueryBuilder.execute()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/ChainableQueryBuilder.html#execute%28%29) | [`RecordStream.getFirstRecord()`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/RecordStream.html#getFirstRecord%28%29) | [`Record.getString(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getString%28java.lang.String%29) | [`Record.getLong(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Record.html#getLong%28java.lang.String%29)

```python
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()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html#aerospike%5Fsdk.aio.session.Session.query) | [`QueryBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.bin) | [`WriteSegmentBuilder.bin()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/write-segment.html#aerospike%5Fsdk.aio.operations.query.WriteSegmentBuilder.bin) | [`RecordStream.first_or_raise()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.first%5For%5Fraise) | [`RecordStream.close()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/record-stream.html#aerospike%5Fsdk.record%5Fstream.RecordStream.close) | [`QueryBuilder.execute()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/query.html#aerospike%5Fsdk.aio.operations.query.QueryBuilder.execute)