# Map operations

## Context

| Context Type | Description |
| --- | --- |
| `MAP_INDEX` | Finds an element in a Map by index. A negative index is a lookup performed in reverse from the end of the map. If it is out of bounds, a parameter error is returned. |
| `MAP_KEY` | Finds an element in a Map by key. |
| `MAP_RANK` | Finds an element in a Map by rank. A negative rank is a lookup performed in reverse from the highest ranked. |
| `MAP_VALUE` | Finds an element in a Map by value. |
| `MAP_KEY_CREATE` | Finds an element in a Map by key. Creates the element if it does not exist. |

The context parameter is a list of context types defining a path to the nested map element the operation should be applied to. Without a context it is assumed that the operation occurs at the top level of the map.

## Write flags

| Flag | Description |
| --- | --- |
| `MODIFY_DEFAULT` | Default: upserts; create or update map keys |
| `CREATE_ONLY` | Only create new map keys. Fail if the key already exists |
| `UPDATE_ONLY` | Only update existing map keys. Fail if a key does not exist |
| `NO_FAIL` | No-op instead of fail if a policy violation occurred, such as `CREATE_ONLY` |
| `DO_PARTIAL` | When used with `NO_FAIL`, add elements that did not violate a policy |

## Return types

| Return Type | Description |
| --- | --- |
| `KEY` | The key of the element (in single result operations) or elements (in multi result operations) |
| `VALUE` | The value of the element (in single result operations) or elements (in multi result operations) |
| `KEY_VALUE` | The key/value pair of the element (in single result operations) or elements (in multi result operations) |
| `ORDERED_MAP` | Returns results as an ordered Map |
| `UNORDERED_MAP` | Returns results as an unordered Map |
| `NONE` | Nothing is returned. It speeds up remove operations by not constructing a reply |
| `COUNT` | Number of elements returned |
| `INDEX` | Key order position of the element, from 0 (smallest key) to N-1 (largest) |
| `REVERSE_INDEX` | Reverse key order position of the element, from 0 (largest key) to N-1 (smallest) |
| `RANK` | Value order of the element, with 0 being the smallest value |
| `REVERSE_RANK` | Reverse value order of the element, with 0 being the largest value |
| `INVERTED` | Invert the search criteria. It can be combined with another return type in the range operations |
| `EXISTS` | If the return type is `EXISTS`, the function returns a `boolean` value. For example, using the Map function [`get_all_by_value`](https://aerospike.com/docs/develop/data-types/collections/map/operations#get_all_by_value) with the return type `EXISTS` returns `true` if the specified value is contained in the Map. The Map function [`get_all_by_value_list`](https://aerospike.com/docs/develop/data-types/collections/map/operations#get_all_by_value_list) with the `EXISTS`, returns `true` if the Map contains any of the specified values. |

Availability

Available since [3.8.4](https://aerospike.com/docs/archived/aerospike-release-notes.html#3.8.4).  
`INVERTED` flag available since [3.16.0](https://aerospike.com/docs/archived/aerospike-release-notes.html#3.16.0.1).  
`NO_FAIL` and `DO_PARTIAL` write flags available since [4.3.0](https://aerospike.com/docs/archived/aerospike-release-notes.html#4.3.0.2).  
Relative rank operations since [4.3.0](https://aerospike.com/docs/archived/aerospike-release-notes.html#4.3.0.2).  
Context available since [4.6.0](https://aerospike.com/docs/archived/aerospike-release-notes.html#4.6.0.2).

## Modify operations

#### `clear`

```python
clear()
```

Description: Clears the map. Map type stays the same.

Returns: null

---

#### `decrement`

```python
decrement(createType, key, delta-value)
```

Description: Decrements values by `delta-value` for all items identified by `key`.

Only works for `integer` or `float` value types in the `{key: value}` pair. Create map bin with `type=createType` if bin did not exist.

#### Type interaction between `value` and `delta-value`

| Value-Type | Delta: `integer` | Delta: `float` |
| --- | --- | --- |
| Map Entry: `integer` | Subtract normally | Truncate to nearest `integer` and subtract |
| Map Entry: `float` | Convert `integer` to `float` and subtract | Subtract normally |

Returns: New value after decrement

---

#### `increment`

```python
increment(createType, key, delta-value)
```

Description: Increments values by `delta-value` for all items identified by `key`.

Only works for `integer` or `float` value types in the `{key: value}` pair. Create map bin with `type=createType` if bin did not exist.

#### Type interaction between `value` and `delta-value`

| Value-Type | Delta: `integer` | Delta: `float` |
| --- | --- | --- |
| Map Entry: `integer` | Add normally | Truncate to nearest `integer` and add |
| Map Entry: `float` | Convert `integer` to `float` and add | Add normally |

Returns: New value after increment

---

#### `put_items`

```python
put_items(bin, items[, writeFlags, createType, context])
```

Description: Creates a map bin with a specified order, if the bin does not exist. Takes a map of key/value items and adds them to the map bin.

Returns: The element count of the map after the operation, in the ‘bins’ part of the record under the _bin_ name.

Order: A map newly created with `put_items` can be optionally declared as `K_ORDERED`, `KV_ORDERED` or `UNORDERED` (default) using the _createType_. In most clients this is the map order attribute of the map policy.

`K_ORDERED` maps are preferred over `UNORDERED` maps, with no real disadvantage in terms of space used.

A note on write flags

Write flags can be combined to alter the behavior of the operation. For example, `CREATE_ONLY | NO_FAIL` will fail gracefully without throwing an exception if an element with the same map key already exists.

Using `DO_PARTIAL` will ensure that any element not violating the policy is added, even on a failed operation.

Code sample: ```python
_, _, bins = client.operate(key, [map_operations.map_put_items("m", {"a":1, "b":{}})])

# {a: 1, b: {}}

print("The map has {} elements".format(bins["m"]))

# The map has 2 elements

ctx = [cdt_ctx.cdt_ctx_map_key("b")]

client.operate(key, [map_operations.map_put_items("m", {"c": 3, "d": 4}, ctx=ctx)])

# {a: 1, b: {c: 3, d: 4}}
```

---

#### `put`

```python
put(bin, key, value[, writeFlags, createType, context])
```

Description: Creates a map bin with a specified order, if the bin does not exist. Adds a key/value element to the map.

Returns: The element count of the map after the operation, in the ‘bins’ part of the record under the _bin_ name.

Order: A map newly created with `put` can be optionally declared as `K_ORDERED`, `KV_ORDERED` or `UNORDERED` (default) using the _createType_. In most clients this is the map order attribute of the map policy.

`K_ORDERED` maps are preferred over `UNORDERED` maps, with no real disadvantage in terms of space used.

A note on write flags

Write flags can be combined to alter the behavior of the operation. For example, `CREATE_ONLY | NO_FAIL` will fail gracefully without throwing an exception if an element with the same map key already exists.

`DO_PARTIAL` is not applicable for this operation.

Performance: For an in-memory namespace, ordered maps will have a 𝓞(log N) worst-case performance. For unordered maps or namespaces not in memory the worst-case performance is 𝓞(N).

Code sample: ```python
# {a: 1}

client.operate(key, [map_operations.map_put("m", "b", {})])

# {a: 1, b: {}}

ctx = [cdt_ctx.cdt_ctx_map_key("b")]

client.operate(key, [map_operations.map_put("m", "c", 3, ctx=ctx)])

# {a: 1, b: {c: 3}}
```

---

#### `remove_all_by_key_list`

```python
remove_all_by_key_list(returnType, keyList)
```

Description: Remove all `{key: value}` pairs where `map.key ∈ keyList`.

Returns: Multi result

---

#### `remove_all_by_value_list`

```python
remove_all_by_value_list(returnType, valueList)
```

Description: Remove all `{key: value}` pairs where `map.value ∈ valueList`.

INDEX result supported since version 3.16.0

Returns: Multi result

---

#### `remove_all_by_value`

```python
remove_all_by_value(returnType, value)
```

Description: Remove all `{key: value}` pairs where `map.value == value`.

Returns: Multi result

---

#### `remove_by_index_range`

```python
remove_by_index_range(returnType, index[, count])
```

Description: Remove all `{key: value}` pairs where `k` = indexof(map.key) and `k >= index` and `k < index + count`. Omitting `count` select element(s) where `k >= origin + index`.

Returns: Multi result

---

#### `remove_by_index`

```python
remove_by_index(returnType, index)
```

Description: Remove `{key: value}` entry where `map.key` is the ith smallest key where `i == index`.

Returns: Single result

---

#### `remove_by_key_interval`

```python
remove_by_key_interval(returnType, keyStart[, keyStop])
```

Description: Remove all `{key: value}` pairs where `map.key >= keyStart` and `map.key < keyStop`. Omitting `keyStop` select element(s) where `map.key >= keyStart`.

Returns: Multi result

---

#### `remove_by_key_rel_index_range`

```python
remove_by_key_rel_index_range(returnType, key, index[, count])
```

Description: Remove all `{key: value}` pairs where `origin` = index(key), `k` = indexof(map.key) and `k >= origin + index` and `k < origin + index + count`. Omitting `count` select element(s) where `k >= origin + index`.

Returns: Multi result

---

#### `remove_by_key`

```python
remove_by_key(returnType, key)
```

Description: Remove entry `{key: value}` where `map.key == key`.

Returns: Single result

---

#### `remove_by_rank_range`

```python
remove_by_rank_range(returnType, rank[, count])
```

Description: Remove all `{key: value}` pairs where `r` = rankof(map.value) and `r >= rank` and `r < rank + count`. Omitting `count` select element(s) where `r >= rank`.

Returns: Multi result

---

#### `remove_by_rank`

```python
remove_by_rank(returnType, rank)
```

Description: Remove `{key: value}` entry where `map.value` is the ith smallest value where `i == rank`.

Returns: Single result

---

#### `remove_by_value_interval`

```python
remove_by_value_interval(returnType, valueStart[, valueStop])
```

Description: Remove all `{key: value}` pairs where `map.value >= valueStart` and `map.value < valueStop`. Omitting `valueStop` select element(s) where `map.value >= valueStart`.

Returns: Multi result

---

#### `remove_by_value_rel_rank_range`

```python
remove_by_value_rel_rank_range(returnType, value, rank[, count])
```

Description: Remove all `{key: value}` pairs where `origin` = rank(value), `r` = rankof(map.value) and `r >= origin + rank` and `r < origin + rank + count`. Omitting `count` select element(s) where `r >= origin + rank`.

Relative operations added since version 4.3.0

Returns: Multi result

---

## Read operations

#### `get_all_by_key_list`

```python
get_all_by_key_list(returnType, keyList)
```

Description: Get all `{key: value}` pairs where `map.key ∈ keyList`.

Returns: Multi result

---

#### `get_all_by_value_list`

```python
get_all_by_value_list(returnType, valueList)
```

Description: Get all `{key: value}` pairs where `map.value ∈ valueList`.

Returns: Multi result

---

#### `get_all_by_value`

```python
get_all_by_value(returnType, value)
```

Description: Get all `{key: value}` pairs where `map.value == value`.

Returns: Multi result

---

#### `get_by_index_range`

```python
get_by_index_range(returnType, index[, count])
```

Description: Get all `{key: value}` pairs where `k` = indexof(map.key) and `k >= index` and `k < index + count`. Omitting `count` select element(s) where `k >= origin + index`.

Returns: Multi result

---

#### `get_by_index`

```python
get_by_index(returnType, index)
```

Description: Get `{key: value}` entry where `map.key` is the ith smallest key where `i == index`.

Returns: Single result

---

#### `get_by_key_interval`

```python
get_by_key_interval(returnType, keyStart[, keyStop])
```

Description: Get all `{key: value}` pairs where `map.key >= keyStart` and `map.key < keyStop`. Omitting `keyStop` select element(s) where `map.key >= keyStart`.

Returns: Multi result

---

#### `get_by_key_rel_index_range`

```python
get_by_key_rel_index_range(returnType, key, index[, count])
```

Description: Get all `{key: value}` pairs where `origin` = index(key), `k` = indexof(map.key) and `k >= origin + index` and `k < origin + index + count`. Omitting `count` select element(s) where `k >= origin + index`.

Returns: Multi result

---

#### `get_by_key`

```python
get_by_key(returnType, key)
```

Description: Get entry `{key: value}` where `map.key == key`.

Returns: Single result

---

#### `get_by_rank_range`

```python
get_by_rank_range(returnType, rank[, count])
```

Description: Get all `{key: value}` pairs where `r` = rankof(map.value) and `r >= rank` and `r < rank + count`. Omitting `count` select element(s) where `r >= rank`.

Returns: Multi result

---

#### `get_by_rank`

```python
get_by_rank(returnType, rank)
```

Description: Get `{key: value}` entry where `map.value` is the ith smallest value where `i == rank`.

Returns: Single result

---

#### `get_by_value_interval`

```python
get_by_value_interval(returnType, valueStart[, valueStop])
```

Description: Get all `{key: value}` pairs where `map.value >= valueStart` and `map.value < valueStop`. Omitting `valueStop` select element(s) where `map.value >= valueStart`.

Returns: Multi result

---

#### `get_by_value_rel_rank_range`

```python
get_by_value_rel_rank_range(returnType, value, rank[, count])
```

Description: Get all `{key: value}` pairs where `origin` = rank(value), `r` = rankof(map.value) and `r >= origin + rank` and `r < origin + rank + count`. Omitting `count` select element(s) where `r >= origin + rank`.

Returns: Multi result

---

#### `size`

```python
size()
```

Returns: Element count

---

## Set operations

#### `set_type`

```python
set_type(type)
```

Description: Modifies the order of an existing map. Order can be `UNORDERED`, `K_ORDERED`, or `KV_ORDERED`

Returns: null

Performance: The worst-case performance of modifying an unordered map to a `K_ORDERED` or `KV_ORDERED` one is 𝓞(N log N).

---