List operations
Contextโ
Context Type | Description |
---|---|
LIST_INDEX | Finds an element in a List by index. A negative index is a lookup performed in reverse from the end of the list. If it is out of bounds, a parameter error is returned. |
LIST_RANK | Finds an element in a List by rank. A negative rank is a lookup performed in reverse from the highest ranked. |
LIST_VALUE | Finds an element in a List by value. |
LIST_INDEX_CREATE | Finds an element in a List by index. Creates the element if it does not exist. |
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 list or map element the operation should be applied to. Without a context it is assumed that the operation occurs at the top level of the List or Map.
Write Flagsโ
Flag | Description |
---|---|
MODIFY_DEFAULT | Default: upserts; not bound by list size; accepts duplicate elements; throws error on failure |
ADD_UNIQUE | Only add elements if they do not already exist in the list |
INSERT_BOUNDED | Do not insert past index N, where N is element count |
NO_FAIL | No-op instead of fail if a policy violation occurred, such as ADD_UNIQUE or INSERT_BOUNDED |
DO_PARTIAL | When used with NO_FAIL , add elements that did not violate a policy |
Return Typesโ
Return Type | Description |
---|---|
VALUE | The value of the element (in single result operations) or elements (in multi result operations) |
NONE | Nothing is returned. It speeds up remove operations by not constructing a reply |
COUNT | Number of elements returned |
INDEX | Index position of the element, from 0 (first) to N-1 (last) |
REVERSE_INDEX | Reverse index position of the element, from 0 (last) to N-1 (first) |
RANK | Value order of the element, with 0 being the smallest |
REVERSE_RANK | Reverse rank 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 List function get_all_by_value with the return type EXISTS , returnstrue if the specified value is contained in the List. The List function get_all_by_value_list with the EXISTS , returns true if the List contains any of the specified values. |
Availabilityโ
EXISTS
available since 6.1.0
NO_FAIL
and DO_PARTIAL
write flags available since 4.3.0.
Relative rank operations since 4.3.0.
Context available since 4.6.0.
In certain older server versions, for ordered lists and a VALUE
return type, an empty list
is always returned.
Affected versions are:
- 3.16.0.1 to 4.6.0.21
- 4.7.0.2 to 4.7.0.19
- 4.8.0.1 to 4.8.0.15
- 4.9.0.3 to 4.9.0.12
- 5.0.0.3 to 5.0.0.13
- 5.1.0.3 to 5.1.0.10
- 5.2.0.2
Set Type Operations
set_order
set_order(bin, order[, context])
Modifies the order of an existing list. Order can be UNORDERED
(default) or ORDERED
.
See CDT Element Ordering and Comparison.
Returns: null
The writeFlags and context are described at the top of this page.
Performance: The set_order
operation does nothing when called on an already ordered list or on an ordered-to-unordered transition. The worst-case performance of modifying an unordered list to an ordered one is ๐(N log N).
See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [4, 5, 8, 1, 2, [3, 2], 9, 6]
# set the inner list (at index 5) to ORDERED
ctx = [
cdt_ctx.cdt_ctx_list_index(5)
]
client.operate(key, [list_operations.list_set_order("l", aerospike.LIST_ORDERED, ctx)])
# [4, 5, 8, 1, 2, [2, 3], 9, 6]
Read Operations
size
size(bin[, context])
Gets the size of a list, optionally at a given subcontext.
Returns: Returns the count of elements in the list at the level specified.
The writeFlags and context are described at the top of this page.
Performance: The worst-case performance of getting the size of the list is ๐(1). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [1, 2, [3, 4]]
k, m, b = client.operate(key, [list_operations.list_size("l")])
print("\nThe size of the list is {}".format(b["l"]))
# The size of the list is 3
# get the size of the inner list (at index 2)
ctx = [
cdt_ctx.cdt_ctx_list_index(2)
]
k, m, b = client.operate(key, [list_operations.list_size("l",ctx=ctx)])
print("\nThe size of the sub-list is {}".format(b["l"]))
# The size of the sub-list is 2
get_by_index
get_by_index(bin, index[, returnType, context])
Gets the element at the specified list index. The index must be a number between 0 and N-1, where N is the length of the list. The index can also be a negative number, with -1 being the last element by index position.
On an ordered list this operation with a VALUE
return type will be the same as a list get_by_rank
operation.
Returns: A single result, based on the return type.
The returnTypes and context are described at the top of this page.
Throws: An Operation Not Applicable error (code 26) when trying to get an inaccessible index.
INDEX
and COUNT
are redundant in this operation. INVERTED
has no meaning in this operation.
Performance: The worst-case performance of getting the element by index is ๐(1) for an ordered list that is stored in memory. Unordered lists, or an ordered list stored on SSD has a ๐(N). See List Performance for the full worst-case performance analysis of the List API.
Example
[1, 3, 3, 7, 0]
modified with set_order
to ORDERED
will turn into [0, 1, 3, 3, 7]
.
The value of the element at index -1 is 7, the rank at -1 is 7.
The value of the element at index 2 is 3, the element with rank 2 is 3.
Code Samples
The following is a Python code sample.
# [1, 4, 7, 3, 9, 26, 11]
# get the value of the element at index 2
client.operate(key, [list_operations.list_get_by_index("l", 2, aerospike.LIST_RETURN_VALUE)])
# 7
client.operate(key, [list_operations.list_get_by_index("l", -2, aerospike.LIST_RETURN_VALUE)])
# 26
get_by_index_range
get_by_index_range(bin, index[, returnType, count, context])
Gets a range of count elements starting at a specified list index. The INVERTED
flag may be used to get the elements not in a specified range.
The index and count can be any number, but the result may be an empty list if the specified range contains no elements.
Returns: One or a list values, based on the return type. The elements returned may not be in index order.
The returnTypes and context are described at the top of this page.
INDEX
is redundant in this operation.
Performance: The worst-case performance of getting elements by index range is ๐(M) for an ordered list that is stored in memory. Unordered lists, or an ordered list stored on SSD has a ๐(N + M), where M is the element count of the range, and N is the element count of the list. See List Performance for the full worst-case performance analysis of the List API.
Example
For [1, 3, 3, 7, 0]
the VALUE
range starting at index 2 and containing 3 elements gives back [3, 7, 0]
, while the INVERTED | VALUE
of the same range gives back [1, 3]
.
Code Samples
The following is a Python code sample.
# [1, 4, 7, 3, 9, 26, 11]
# get two elements starting at index 2
client.operate(key, [list_operations.list_get_by_index_range("l", 2, aerospike.LIST_RETURN_VALUE, 2)])
# [7, 3]
get_by_rank
get_by_rank(bin, rank[, returnType, context])
Gets the element with the specified rank order. The rank must be a number between 0 (lowest rank) and N-1 (highest rank), where N is the length of the list. The rank can also be a negative number, with -1 being the element with the highest rank.
On an ordered list this operation with a VALUE
return type will be the same as a list get_by_index
operation, (see this example).
Whether the list is unordered or ordered, get_by_rank
will return the same elements, based on the ordering rules. The performance of 'by rank' operations is better on an ordered list than an unordered one.
Returns: A single result, based on the return type.
The returnTypes and context are described at the top of this page.
Throws: An Operation Not Applicable error (code 26) when trying to get an inaccessible rank.
RANK
and COUNT
are redundant in this operation. INVERTED
has no meaning in this operation.
Performance: The worst-case performance of getting an element by rank is ๐(1) for an ordered list that is stored in memory, ๐(N) for an ordered list stored on SSD, and ๐(R log N + N) for an unordered list. See List Performance for the full worst-case performance analysis of the List API.
Example
[1, 3, [3, 7], 0, [3, 2]]
modified with set_order
to ORDERED
will turn into [0, 1, 3, [3, 2], [3, 7]]
, because a list has higher ranking order than integers, and the list elements are compared by index when sorted.
Code Samples
The following is a Python code sample.
# [1, 4, 7, 3, 9, 26, 11]
# get the value of the element with the second highest rank
client.operate(key, [list_operations.list_get_by_rank("l", -2, aerospike.LIST_RETURN_VALUE)])
# 11
client.operate(key, [list_operations.list_get_by_rank("l", 2, aerospike.LIST_RETURN_VALUE)])
# 4
get_by_rank_range
get_by_rank_range(bin, rank[, returnType, count, context])
Gets a range of count elements starting at a specified rank. The INVERTED
flag may be used to get the elements not in a specified range.
The rank and count can be any number, but the result may be an empty list if the specified range contains no elements.
Returns: One or a list of values, based on the return type. The elements returned may not be in rank order.
The returnTypes and context are described at the top of this page.
INDEX
is redundant in this operation.
Performance: The worst-case performance of getting elements by rank range is ๐(M) for an ordered list that is stored in memory. An ordered list stored on SSD has a ๐(N + M), where M is the element count of the range, and N is the element count of the list. An unordered list has a ๐(R log N + N). See List Performance for the full worst-case performance analysis of the List API.
Example
For [1, 3, 2, 7, 0]
the VALUE
range starting at rank 2 and containing 2 elements gives back [2, 3]
, while the INVERTED | VALUE
of the same range gives back [0, 1, 7]
.
Code Samples
The following is a Python code sample.
# [1, 4, 7, 3, 9, 26, 11]
# get the top three ranked elements
client.operate(key, [list_operations.list_get_by_rank_range("l", -3, aerospike.LIST_RETURN_VALUE, 3)])
# [9, 11, 26]
get_all_by_value
get_all_by_value(bin, value[, returnType, context])
Gets all the elements in the list matching value. The INVERTED
flag may be used to get the elements not matching the specified value.
Whether the list is unordered or ordered, get_all_by_value
will return the same elements, based on the ordering rules. The performance of 'by value' operations is better on an ordered list than an unordered one.
Returns: Zero, one or a list of values, based on the return type. The elements returned may not be in index order.
The returnTypes and context are described at the top of this page.
Performance: The worst-case performance of getting elements by value is ๐(log N + M) for an ordered list that is stored in memory, ๐(log N + N) for an ordered list stored on SSD, and ๐(N + M) for an unordered list, where M is the number of items in the parameter list and N is the number of items already in the list. See List Performance for the full worst-case performance analysis of the List API.
Trivial Example
Count the number of elements in the list with a specified scalar value.
# [1, 2, 1, 2]
# count all the elements whose value is 2
client.operate(key, [list_operations.list_get_by_value("l", 2, aerospike.LIST_RETURN_COUNT)])
# 2
Matching Tuples with Wildcard
It is common to model complex data in Aerospike as a list of tuples, each element a list, where the index order carries meaning. For an example, see Aerospike Modeling: IoT Sensors.
In a list of mostly ordered pairs, we could search for a specific kind of element, such as all the tuples where the 0th position is "v2", by using a wildcard (typically stylized as a * in documentation).
# [["v1", 1], ["v2", 2], ["v1", 3], ["v2", 4, {"a": 1}]]
key, metadata, bins = client.operate(
key,
[
list_operations.list_get_by_value(
"l", ["v2", aerospike.CDTWildcard()], aerospike.LIST_RETURN_VALUE
)
],
)
print(bins["l"])
# [["v2", 2], ["v2", 4, {"a": 1}]]
The wildcard matches any sequence of elements to the end of the tuple. In this example, this means matching any tuple whose first position is "v2", and whose size is two or more elements.
The wildcard has different language-specific constructs, such as aerospike.CDTWildcard()
in the Python client and Value.WildcardValue
in the Java client.
Code Samples
See the examples above, or follow any of these language-specific links for detailed code examples for the operation.
get_all_by_value_list
get_all_by_value_list(bin, values [, returnType, context])
Gets all the elements in the list matching one of the specified values. The INVERTED
flag may be used to get the elements not matching any of the values.
Whether the list is unordered or ordered, get_all_by_value_list
will return the same elements, based on the ordering rules. The performance of 'by value' operations is better on an ordered list than an unordered one.
Returns: Zero, one or a list of values, based on the return type. The elements returned may not be in index order.
The returnTypes and context are described at the top of this page.
Performance: The worst-case performance of getting elements by a value list is ๐((M+N) log M) for an ordered list that is stored in memory, ๐((M+N) log M + N) for an ordered list stored on SSD, or for an unordered list, where M is the number of items in the parameter list and N is the number of items already in the list. See List Performance for the full worst-case performance analysis of the List API.
Trivial Example
Count the number of elements in the list with a specified scalar value.
# [1, 2, 3, 2, 1]
# count all the elements whose value is 2 or 3
client.operate(key, [list_operations.list_get_by_value_list("l", [2, 3], aerospike.LIST_RETURN_COUNT)])
# 3
Matching Tuples with Wildcard
See the example given for get_all_by_value
.
In a list of mostly ordered pairs, we could search for all the tuples that do not start with "v1" or "v2", by using a wildcard and an INVERTED | VALUE
return type.
# [["v1", 1], ["v2", 2], ["v3", 3], ["v2", 4]]
wildcard = aerospike.CDTWildcard()
key, metadata, bins = client.operate(
key,
[
list_operations.list_get_by_value_list(
"l", [["v2", wildcard], ["v1", wildcard]],
aerospike.LIST_RETURN_VALUE, inverted=True,
)
],
)
print(bins["l"])
# [["v3", 3]]
The wildcard matches any sequence of elements to the end of the tuple. In this example, this means matching any tuple whose first position is "v1" or "v2", and whose size is two or more elements.
The wildcard has different language-specific constructs, such as aerospike.CDTWildcard()
in the Python client and Value.WildcardValue
in the Java client.
Code Samples
See the examples above, or follow any of these language-specific links for detailed code examples for the operation.
get_by_value_interval
get_by_value_interval(bin, valueStart, valueStop[, returnType, context])
Gets the list elements that sort into the interval between valueStart (inclusive) and valueStop (exclusive). The INVERTED
flag may be used to get the elements outside this interval.
Whether the list is unordered or ordered, get_by_value_interval
will return the same elements, based on the ordering rules. The performance of 'by value' operations is better on an ordered list than an unordered one.
Returns: Zero, one or a list of values, based on the return type. The elements returned may not be in index order.
The returnTypes and context are described at the top of this page.
Performance: The worst-case performance of getting elements in a value interval is ๐(log N + M) for an ordered list that is stored in memory, ๐(log N + N) for an ordered list stored on SSD, and ๐(N + M) for an unordered list, where M is the number of items in the parameter list and N is the number of items already in the list. See List Performance for the full worst-case performance analysis of the List API.
Trivial Example
Get the list elements in the interval between two scalar values.
# [1, 2, 3, 4, 5, 4, 3, 2, 1]
# get all the elements in the interval [2, 4)
client.operate(key, [list_operations.list_get_by_value("l", aerospike.LIST_RETURN_VALUE, 2, 4)])
# [2, 3, 3, 2]
Interval Comparison of Tuples
It is common to model complex data in Aerospike as a list of tuples, each element a list, where the index order carries meaning. For an example, see Aerospike Modeling: IoT Sensors.
This modeling relies on the ordering rules that apply to list elements. Ordered pairs sort into
[1, NIL]
< [1, 1]
< [1, 1, 2]
< [1, 2]
< [1, '1']
< [1, 1.0]
< [1, INF]
Take the list of ordered pairs, [[100, 1], [101, 2], [102, 3], [103, 4], [104, 5]]
and the following intervals:
valueStart: [101, NIL]
, valueStop: [103, NIL]
Iterating over the elements we check if [101, NIL] <= value < [103, NIL]
. This is true for the elements [101, 2]
and [102, 3]
. The element [103, 4]
is not in this interval, because its order is higher than [103, NIL]
. The comparison starts with the 0th index values, in this case both are 103. Next the 1st index position values are compared, and NIL
is lower than 3 (actually its order is lower than any value).
valueStart: [101, NIL]
, valueStop: [103, INF]
The elements [101, 2]
and [102, 3]
are obviously in the interval. The element [103, 4]
is also in this interval, because its order is lower than [103, INF]
. The comparison starts with the 0th index values, in this case both are 103. Next the 1st index position values are compared, and INF
is higher than 3 (actually its order is higher than any value).
valueStart: [101, INF]
, valueStop: [103, INF]
The elements [102, 2]
and [103, 4]
are in the interval. The element [101, 2]
is not in this interval, because its order is lower than [101, INF]
.
Code Samples
The following is a Python code sample.
# [[100, 1], [101, 2], [102, 3], [103, 4], [104, 5]]
# get_by_value_interval(VALUE, [103, NIL], [103, INF])
key, metadata, bins = client.operate(
key,
[
list_operations.list_remove_by_value(
"l", aerospike.LIST_RETURN_VALUE,
[101, aerospike.null()], [103, aerospike.CDTInfinite()]
),
],
)
print(bins["l"])
# [[101, 2], [102, 3], [103, 4]]
get_by_value_rel_rank_range
get_by_value_rel_rank_range(bin, value, rank, returnType[, count, context])
Gets a range of count elements starting at a rank offset from the relative rank of the given value. The INVERTED
flag may be used to get the elements not in this range.
The value can be anything, not necessarily a value that exists in the list. The rank and count can be any number, but the result may be an empty list if the specified range contains no elements.
The relative rank of the value compared to the current list follows the ordering rules.
Returns: Zero, one or a list of values, based on the return type. The elements returned may not be in index order.
The returnTypes and context are described at the top of this page.
Formula:
origin = relative-rank(_value_) # compared to the current list elements
r = rank(element)
Get all elements in the range where
(r >= (origin + _rank_)) and (r < (origin + _rank_ + _count_))
Performance: The worst-case performance of getting elements by relative rank range is ๐(M + log N) for an ordered list that is stored in memory. An ordered list stored on SSD has a ๐(N + M + log N), where M is the element count of the range, and N is the element count of the list. An unordered list has a ๐(R log N + N), with R for rank. See List Performance for the full worst-case performance analysis of the List API.
Example
For [0, 3, 9, 12, 15]
a value of 5 would rank between 3 and 9, relative to the current list. A rank of -1 from there would select 3 as the starting point of the range, and then the count would select the elements. So a count of 3 would return the range 3, 9 and 12.
Code Samples
The following is a Python code sample.
world_records = [
[10.03, "Jim Hines", "Sacramento, USA", "June 20, 1968"],
[10.02, "Charles Greene", "Mexico City, Mexico", "October 13, 1968"],
[9.95, "Jim Hines", "Mexico City, Mexico", "October 14, 1968"],
[9.93, "Calvin Smith", "Colorado Springs, USA", "July 3, 1983"],
[9.93, "Carl Lewis", "Rome, Italy", "August 30, 1987"],
[9.92, "Carl Lewis", "Seoul, South Korea", "September 24, 1988"],
]
nil = aerospike.null() # NIL
# Python client equivalent of get_by_value_rel_rank_range("l", [10.0, NIL], -1, VALUE, 2)
key, metadata, bins = client.operate(
key,
[
operations.write("l", world_records),
list_operations.list_get_by_value_rank_range_relative(
"l", [10.0, nil], -1, aerospike.LIST_RETURN_VALUE, 2
),
],
)
print(bins["l"])
# The two closest world records to 10.0s are
# [
# [9.95, 'Jim Hines', 'Mexico City, Mexico', 'October 14, 1968'],
# [10.02, 'Charles Greene', 'Mexico City, Mexico', 'October 13, 1968']]
Modify Operations
clear
clear(bin[, context])
Clears a list, optionally at a given subcontext.
Returns: null
The writeFlags and context are described at the top of this page.
Performance: The worst-case performance of clearing a list is ๐(1). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [1, 2, [3, 4]]
ctx = [
cdt_ctx.cdt_ctx_list_index(2)
]
client.operate(key, [list_operations.list_clear("l",ctx=ctx)])
# [1, 2, []]
sort
sort(bin[, sortFlags, context])
Sorts a list, but doesn't change the list order. An unordered list will remain unordered after being sorted. An ordered list doesn't need to be sorted, because by definition it sorts itself any time elements are added to it.
Returns: null
The writeFlags and context are described at the top of this page.
Sort Flags:
Flag | Description |
---|---|
DEFAULT | Default keep duplicates |
DROP_DUPLICATES | Drop duplicates while sorting |
Performance: The sort operation will do no work when called on an already ordered list. The worst-case performance of sorting an unordered list is ๐(N log N). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [5, 1, 8, 2, 7, [3, 2, 4, 1], 9, 6, 1, 2]
# sort the inner list (at index 5)
ctx = [
cdt_ctx.cdt_ctx_list_index(5)
]
client.operate(key, [list_operations.list_sort("l",ctx=ctx)])
# [5, 1, 8, 2, 7, [1, 2, 3, 4], 9, 6, 1, 2]
append
append(bin, value[, writeFlags, context])
Creates a list bin with a specified order, if the bin does not exist. Adds a value to the list. In an UNORDERED
list the value is appended to the end of the list. In an ORDERED
list the value is inserted by value order.
Returns: The element count due to the operation, in the 'bins' part of the record under the bin name.
The writeFlags and context are described at the top of this page.
Order: A list newly created with append
can be declared UNORDERED
(default) or ORDERED
using the list order attribute of the list policy. Once a list is created its order can only be modified with set_order
.
Write flags can be combined to alter the behavior of the operation. For example, ADD_UNIQUE | NO_FAIL
will fail gracefully without throwing an exception if the element already exists.
INSERT_BOUNDED
and DO_PARTIAL
are not applicable for this operation.
Performance: The worst-case performance of append() on an unordered list is ๐(N). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [1, [2]]
# append to the list element at index 1
ctx = [cdt_ctx.cdt_ctx_list_index(1)]
client.operate(key, [list_operations.list_append("l", 3, ctx=ctx)])
# [1, [2, 3]]
append_items
append_items(bin, items[, writeFlags, context])
Creates a list bin with a specified order, if the bin does not exist. Adds the items to the list. In an UNORDERED
list the items are appended to the end of the list. In an ORDERED
list the items are inserted by value order.
Returns: The element count due to the operation, in the 'bins' part of the record under the bin name.
The writeFlags and context are described at the top of this page.
Order: A list newly created with append_items
can be declared UNORDERED
(default) or ORDERED
using the list order attribute of the list policy. Once a list is created its order can only be modified with set_order
.
Write flags can be combined to alter the behavior of the operation. For example, ADD_UNIQUE | NO_FAIL
will fail gracefully without throwing an exception if any new item already exists.
INSERT_BOUNDED
is not applicable for this operation.
Performance: The worst-case performance of append_items on an unordered list is ๐(M), and ๐((M+N) log (M+N)) on an ordered list, where M is the number of items to append and N is the number of items already in the list. See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [1, 2, [3]]
# append items to the sub list at index 2
ctx = [cdt_ctx.cdt_ctx_list_index(2)]
client.operate(key, [list_operations.list_append_items("l", [4, 5], ctx=ctx)])
# [1, 2, [3, 4, 5]]
insert
insert(bin, index, value[, writeFlags, context])
Creates an unordered list bin, if the bin does not exist. Inserts a value into the list at the specified index, and shifts elements with a higher index to the right of the new element.
By default the index can be any number, and NIL
values will be added as padding to the left of the new element, as needed. Using the INSERT_BOUNDED
policy, a developer can limit this behavior, and only allow for an element to be inserted at an index value between 0 and the size of the list.
you cannot insert into an ordered list, only append
or append_items
to one.
Returns: The element count due to the operation, in the 'bins' part of the record under the bin name.
The writeFlags and context are described at the top of this page.
Order: A list newly created with insert
is always unordered. Once a list is created its order can only be modified with set_order
.
Write flags can be combined to alter the behavior of the operation. For example, ADD_UNIQUE | NO_FAIL
will fail gracefully without throwing an exception if any new item already exists.
DO_PARTIAL
is not applicable for this operation, as we only insert one element at a time.
Performance: The worst-case performance of inserting an item at the head of a list (at its 0th index) is ๐(1). At any other index it is ๐(N). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [None, 'c'] - Aerospike NIL represented as a Python None instance
# insert another element into the existing list
client.operate(key, [list_operations.list_insert("l", 1, "b")])
# [None, 'b', 'c']
set
set(bin, index, value[, writeFlags, context])
Creates an unordered list bin, if the bin does not exist. Sets or overwrites a value at the specified list index. (This set function has no relation to the Aerospike concept of sets as a collection of records.)
By default the index can be any number, and NIL values will be added as padding to the left of the new element, as needed. Using the INSERT_BOUNDED
policy, a developer can limit this behavior, and only allow for an element to be set at an index value between 0 and the size of the list.
You cannot set a value in an ordered list, only append or append_items to one.
Returns: The element count due to the operation, in the 'bins' part of the record under the bin name.
The writeFlags and context are described at the top of this page.
Order: A list newly created with set()
is always unordered.
Write flags can be combined to alter the behavior of the operation. For example, ADD_UNIQUE | NO_FAIL
will fail gracefully without throwing an exception if the element already exists.
DO_PARTIAL
is not applicable for this operation, as we only set one element at a time.
Performance: The worst-case performance of setting an item at the head of a list (at its 0th index) is ๐(1). At any other index it is ๐(N). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [None, 'b']
# set an element at right the boundary of the current list (index == count)
# with a INSERT_BOUNDED write flags
policy = {
"write_flags": aerospike.LIST_WRITE_INSERT_BOUNDED
| aerospike.LIST_WRITE_NO_FAIL
}
client.operate(key, [list_operations.list_set("l", 2, "c", policy)])
# [None, 'b', 'c']
More Code Samples: Python
increment
increment(bin, index, delta-value[, writeFlags, context])
Creates an unordered list bin if the bin does not exist. In an UNORDERED
list, increment() initializes or increments a numeric value at the specified list index. In an ORDERED
list, increments a numeric value at a specific rank, given by the index argument.
By default the index can be any number, and NIL
values will be added as padding to the left of the new element, as needed. Using the INSERT_BOUNDED
policy, a developer can limit this behavior, and only allow for an element to be incremented at an index value between 0 and the size of the list.
Increment delta values can be either float or integer. An integer delta value will be converted into a float if the server-side type is a float. A float delta-value will be converted and truncated into an integer if the server-side value is an integer.
Returns: The new value after the increment, in the 'bins' part of the record under the bin name.
The writeFlags and context are described at the top of this page.
Order: A list newly created with increment
is always unordered. Once a list is created its order can only be modified with set_order
.
Write flags can be combined to alter the behavior of the operation. For example, ADD_UNIQUE | NO_FAIL
will fail gracefully without throwing an exception if the element already exists.
DO_PARTIAL
is not applicable for this operation, as we only increment one element at a time.
Performance: The worst-case performance of increment() on an unordered list is ๐(N). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [1, 2.1]
client.operate(key, [list_operations.list_increment("l", 1, 2.1)])
# [1, 4.2]
remove_by_index
remove_by_index(bin, index[, returnType, context])
Removes the element at the specified list index. The index must be a number between 0 and N-1, where N is the length of the list. The index can also be a negative number, with -1 being the last element by index position.
Returns: Zero or one value, based on the return type. The NONE
return type will execute faster because no reply is constructed for the operation.
The returnTypes and context are described at the top of this page.
Throws: An Operation Not Applicable error (code 26) when trying to remove an inaccessible index.
INDEX
and COUNT
are redundant for this operation. INVERTED
has no meaning for this operation.
Performance: The worst-case performance of removing the element by index is ๐(1) for an ordered list that is stored in memory. Unordered lists, or an ordered list stored on SSD has a ๐(N). See List Performance for the full worst-case performance analysis of the List API.
Code Samples
The following is a Python code sample.
# [1, 4, 7, 3, 9, 26, 11]
# remove the value of the element at index 2
client.operate(key, [list_operations.list_remove_by_index("l", 2, aerospike.LIST_RETURN_VALUE)])
# 7
client.operate(key, [list_operations.list_remove_by_index("l", -2, aerospike.LIST_RETURN_VALUE)])
# 26
remove_by_index_range
remove_by_index_range(bin, index[, returnType, count, context])
Removes a range of count elements starting at a specified list index. The INVERTED
flag may be used to remove the elements not in a specified range.
The index and count can be any number, but the result may be an empty list if the specified range contains no elements.
Returns: Zero, one or a list of values, based on the return type. The NONE
return type will execute faster because no reply is constructed for the operation. The elements returned by other return types may not be in index order.
The returnTypes and context are described at the top of this page.
INDEX
is redundant for this operation.
Performance: The worst-case performance of removing elements by index range is ๐(M) for an ordered list that is stored in memory. Unordered lists, or an ordered list stored on SSD has a ๐(N + M), where M is the element count of the range, and N is the element count of the list. See List Performance for the full worst-case performance analysis of the List API.
Example
For [1, 3, 3, 7, 0]
with return type NONE
a range starting at index 2 and containing 3 elements removes [3, 7, 0]
, while the INVERTED | NONE
of the same range removes [1, 3]
.
Code Samples
The following is a Python code sample.
# [1, 4, 7, 3, 9, 26, 11]
# remove a range of 2 element starting at index -2
client.operate(key, [list_operations.list_remove_by_index_range("l", 2, aerospike.LIST_RETURN_VALUE, 2)])
# [26, 11]
remove_by_rank_range
remove_by_rank_range(bin, rank[, returnType, count, context])
Removes a range of count elements starting at a specified rank. The INVERTED
flag may be used to remove the elements not in a specified range.
The rank and count can be any number, but the result may be an empty list if the specified range contains no elements.
Returns: Zero, one or a list of values, based on the return type. The NONE
return type will execute faster because no reply is constructed for the operation. The elements returned by other return types may not be in rank order.
The returnTypes and context are described at the top of this page.
INDEX
is redundant for this operation.
Performance: The worst-case performance of removing elements by rank range is ๐(M) for an ordered list that is stored in memory. An ordered list stored on SSD has a ๐(N + M), where M is the element count of the range, and N is the element count of the list. An unordered list has a ๐(R log N + N). See List Performance for the full worst-case performance analysis of the List API.
Example
[1, 3, [3, 7], 0, [3, 2]]
modified with set_order
to ORDERED
will turn into [0, 1, 3, [3, 2], [3, 7]]
, because a list has higher ranking order than integers, and the list elements are compared by index when sorted.
Code Samples
The following is a Python code sample.
# [1, 4, 7, 3, 9, 26, 11]
# remove the top three ranked elements
client.operate(key, [list_operations.list_remove_by_rank_range("l", -3, aerospike.LIST_RETURN_VALUE, 3)])
# [9, 11, 26]
remove_all_by_value
remove_all_by_value(bin, value[, returnType, context])
Removes all the elements in the list matching value. The INVERTED
flag may be used to remove the elements not matching the specified value.
Returns: Zero, one or a list of values, based on the return type. The NONE
return type will execute faster because no reply is constructed for the operation. The elements returned by other return types may not be in index order.
The returnTypes and context are described at the top of this page.
Order: Whether the list is unordered or ordered, remove_all_by_value
will return the same elements, based on the ordering rules. The performance of 'by value' operations is better on an ordered list than an unordered one.
Performance: The worst-case performance of removing elements by value is ๐(log N + M) for an ordered list that is stored in memory, ๐(log N + N) for an ordered list stored on SSD, and ๐(N + M) for an unordered list, where M is the number of items in the parameter list and N is the number of items already in the list. See List Performance for the full worst-case performance analysis of the List API.
Trivial Example
Remove scalar values from the list.
# [1, 2, 1, 2]
# remove all the elements whose value is 2, and get the count of removed elements
client.operate(key, [list_operations.list_remove_by_value("l", 2, aerospike.LIST_RETURN_COUNT)])
# 2
Matching Tuples with Wildcard
It is common to model complex data in Aerospike as a list of tuples, each element a list, where the index order carries meaning. For an example, see Aerospike Modeling: IoT Sensors.
In a list of mostly ordered pairs, we could remove a specific kind of element, such as all the tuples where the 0th position is "v2", by using a wildcard (typically stylized as a * in documentation).
# [["v1", 1], ["v2", 2], ["v1", 3], ["v2", 4, {"a": 1}]]
key, metadata, bins = client.operate(
key,
[
list_operations.list_remove_by_value(
"l", ["v2", aerospike.CDTWildcard()], aerospike.LIST_RETURN_VALUE
)
],
)
print(bins["l"])
# [["v2", 2], ["v2", 4, {"a": 1}]]
The wildcard matches any sequence of elements to the end of the tuple. In this example, this means matching any tuple whose first position is "v2", and whose size is two or more elements.
The wildcard has different language-specific constructs, such as aerospike.CDTWildcard()
in the Python client and Value.WildcardValue
in the Java client.
Code Samples
See the examples above, or follow any of these language-specific links for detailed code examples for the operation.
remove_all_by_value_list
remove_all_by_value_list(bin, values[, returnType, context])
Removes all the elements in the list matching one of the specified values. The INVERTED
flag may be used to remove the elements not matching the specified values.
Returns: Zero, one or a list of values, based on the return type. The NONE
return type will execute faster because no reply is constructed for the operation. The elements returned by other return types may not be in index order.
The returnTypes and context are described at the top of this page.
Order: Whether the list is unordered or ordered, remove_all_by_value_list
will return the same elements, based on the ordering rules. The performance of 'by value' operations is better on an ordered list than an unordered one.
Performance: The worst-case performance of removing elements by a value list is ๐((M+N) log M) for an ordered list that is stored in memory, ๐((M+N) log M + N) for an ordered list stored on SSD, or for an unordered list, where M is the number of items in the parameter list and N is the number of items already in the list. See List Performance for the full worst-case performance analysis of the List API.
Trivial Example
Remove scalar values from the list.
# [1, 2, 3, 4, 3, 2, 1]
# remove all the elements whose value are 2 or 3, and get the count of removed elements
client.operate(key, [list_operations.list_remove_by_value_list("l", [2, 3], aerospike.LIST_RETURN_COUNT)])
# 4
Matching Tuples with Wildcard
See the example given for remove_all_by_value
.
In a list of mostly ordered pairs, we could remove all the tuples matching the patterns [v1, \*]
and [v2, \*]
.
# [["v1", 1], ["v2", 2], ["v3", 3], ["v2", 4], ["v1", 5]]
key, metadata, bins = client.operate(
key,
[
list_operations.list_remove_by_value_list(
"l", [["v1", aerospike.CDTWildcard()], ["v2", aerospike.CDTWildcard()]],
aerospike.LIST_RETURN_NONE
),
operations.read("l"),
],
)
print(bins["l"])
# [["v3", 3]]
The wildcard matches any sequence of elements to the end of the tuple. In this example, this means matching any tuple whose first position is "v1" or "v2", and whose size is two or more elements.
The wildcard has different language-specific constructs, such as aerospike.CDTWildcard()
in the Python client and Value.WildcardValue
in the Java client.
Code Samples
See the examples above, or follow any of these language-specific links for detailed code examples for the operation.
remove_by_value_interval
remove_by_value_interval(bin, valueStart, valueStop[, returnType, context])
Removes the list elements that sort into the interval between valueStart (inclusive) and valueStop (exclusive). The INVERTED
flag may be used to remove the elements outside this interval.
Returns: Zero, one or a list of values, based on the return type. The elements returned may not be in index order.
The returnTypes and context are described at the top of this page.
Order: Whether the list is unordered or ordered, remove_by_value_interval
will return the same elements, based on the ordering rules. The performance of 'by value' operations is better on an ordered list than an unordered one.
Performance: The worst-case performance of removing elements in a value interval is ๐(log N + M) for an ordered list that is stored in memory, ๐(log N + N) for an ordered list stored on SSD, and ๐(N + M) for an unordered list, where M is the number of items in the parameter list and N is the number of items already in the list. See List Performance for the full worst-case performance analysis of the List API.
Trivial Example
Remove the list elements in the interval between two scalar values.
# [1, 2, 3, 4, 5, 4, 3, 2, 1]
# remove all the elements in the interval [2, 4), then read the bin
client.operate(
key,
[
list_operations.list_remove_by_value("l", aerospike.LIST_RETURN_NONE, 2, 4),
operations.read("l"),
],
)
# [1, 4, 5, 4, 1]
Interval Comparison of Tuples
It is common to model complex data in Aerospike as a list of tuples, each element a list, where the index order carries meaning. For an example, see Aerospike Modeling: IoT Sensors.
This modeling relies on the ordering rules that apply to list elements. Ordered pairs sort into
[1, NIL]
< [1, 1]
< [1, 1, 2]
< [1, 2]
< [1, '1']
< [1, 1.0]
< [1, INF]
Take the list of ordered pairs, [[100, 1], [101, 2], [102, 3], [103, 4], [104, 5]]
and the following intervals:
valueStart: [101, NIL]
, valueStop: [103, NIL]
Iterating over the elements we check if [101, NIL] <= value < [103, NIL]
. This is true for the elements [101, 2]
and [102, 3]
. The element [103, 4]
is not in this interval, because its order is higher than [103, NIL]
. The comparison starts with the 0th index values, in this case both are 103. Next the 1st index position values are compared, and NIL
is lower than 3 (actually its order is lower than any value).
valueStart: [101, NIL]
, valueStop: [103, INF]
The elements [101, 2]
and [102, 3]
are obviously in the interval. The element [103, 4]
is also in this interval, because its order is lower than [103, INF]
. The comparison starts with the 0th index values, in this case both are 103. Next the 1st index position values are compared, and INF
is higher than 3 (actually its order is higher than any value).
valueStart: [101, INF]
, valueStop: [103, INF]
The elements [102, 2]
and [103, 4]
are in the interval. The element [101, 2]
is not in this interval, because its order is lower than[101, INF]
.
Code Samples
The following is a Python code sample.
# [[100, 1], [101, 2], [102, 3], [103, 4], [104, 5]]
# remove_by_value_interval(VALUE, [103, NIL], [103, INF])
key, metadata, bins = client.operate(
key,
[
list_operations.list_remove_by_value(
"l", aerospike.LIST_RETURN_VALUE,
[101, aerospike.null()], [103, aerospike.CDTInfinite()]
),
],
)
print(bins["l"])
# [[101, 2], [102, 3], [103, 4]]
remove_by_value_rel_rank_range
remove_by_value_rel_rank_range(bin, value, rank, returnType[, count, context])
Removes a range of count elements starting at a specified rank, relative to the given value. The INVERTED
flag may be used to remove the elements not in a specified range.
The value can be anything, not necessarily a value that exists in the list. The rank and count can be any number, but the result may be an empty list if the specified range contains no elements.
Returns: Zero, one or a list of values, based on the return type. The elements returned may not be in rank order.
The returnTypes and context are described at the top of this page.
Order: The relative rank of the value compared to the current list follows the ordering rules.
Performance: The worst-case performance of removing elements by relative rank range is ๐(M + log N) for an ordered list that is stored in memory. An ordered list stored on SSD has a ๐(N + M + log N), where M is the element count of the range, and N is the element count of the list. An unordered list has a ๐(R log N + N), with R for rank. See List Performance for the full worst-case performance analysis of the List API.
Example
For [0, 3, 9, 12, 15]
a value of 5 would rank between 3 and 9, relative to the current list. A rank of -1 from there would select 3 as the starting point of the range, and then the count would select the elements. So a count of 3 would remove the elements 3, 9 and 12.
Code Samples
The following is a Python code sample.
tuples = [
[1968, 10.03],
[1968, 10.02],
[1968, 9.95],
[1983, 9.93],
[1987, 9.93],
[1988, 9.92],
]
nil = aerospike.null() # NIL
key, metadata, bins = client.operate_ordered(
key,
[
operations.write("l", tuples),
lops.list_remove_by_value_rank_range_relative(
"l", [1973, nil], -1, aerospike.LIST_RETURN_VALUE, 2
),
operations.read("l"),
],
)
print("removed {}".format(bins[0][1]))
# removed [[1983, 9.93], [1968, 10.03]]
# this is because ranking of list type elements is done by index, so all ordered pairs
# with a 1968 in the 0th index position are lower than those starting 1983, 1987, 1988
# within the 1968 group they're ranked by their 1st index position, with 10.03
# ranked the highest, closest to [1983, 9.93]. [1973, nil] falls between the
# two when its rank is considered relative to the list values.
print("remaining {}".format(bins[1][1]))
# remaining [[1968, 10.02], [1968, 9.95], [1987, 9.93], [1988, 9.92]]