Skip to content

Examples for List operations

For the complete documentation index see: llms.txt

All documentation pages available in markdown.

Use Aerospike lists to implement use cases when working with any of the following:

  • Queues
  • Unique ordered data
  • Time series containers
  • Leaderboards
  • Membership lists for user profiles

Each one of the list operations has a detailed description with code examples.

Modeling concepts

An Aerospike list can be used to express a many-to-one relationship in a single record. By comparison in a relational database, such a relationship would span multiple rows in two tables.

For example, a user and her vehicles would likely be expressed in a relational database as a users table and a vehicles table, with a vehicles.user_id column indexed and declared to be a foreign key to users.

In Aerospike a Users set would contain user records. Each user’s vehicles could be expressed as a list of map elements, with each map element containing the information of one vehicle. Users without any vehicles would not have a vehicles bin at all. In Aerospike, sets have no schema, and records can vary from one another in their structure. There is no necessity to place-hold vehicles with something like a NULL in a relational database.

Examples

Lists as queues

Starting from an unordered list in the lqueue bin:

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]

Enqueue two elements

Enqueue two new elements at the same time, using a single atomic operate call with two list_append operations. After this call, the list has 16 elements.

try (RecordStream rs = session.upsert(key)
.bin("lqueue").listAppend(377)
.bin("lqueue").listAppend(477)
.execute()) {
Record rec = rs.next().recordOrThrow();
}
// lqueue: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 477]

Dequeue two elements

Dequeue the first two values with one atomic list operation. The remove_by_index_range operation removes elements starting at index 0, with a count of 2.

try (RecordStream rs = session.upsert(key)
.bin("lqueue").onListIndexRange(0, 2).removeAnd().getValues()
.execute()) {
List<?> removed = rs.next().recordOrThrow().getList("lqueue");
// removed: [0, 1]
}
// lqueue: [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 477]

Enqueue and dequeue atomically

Use a single operate call to enqueue a new element while dequeuing the first element in the queue.

try (RecordStream rs = session.upsert(key)
.bin("lqueue").listAppend(125)
.bin("lqueue").onListIndexRange(0, 1).removeAnd().getValues()
.execute()) {
List<?> removed = rs.next().recordOrThrow().operationResult(1).getList();
// removed: [1]
}
// lqueue: [2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 477, 125]

Lists as containers for time series data

A record contains a list of [timestamp, value] pairs in the pairs bin:

[
[1523474230000, 39.04],
[1523474231001, 39.78],
[1523474236006, 40.07],
[1523474235005, 41.18],
[1523474233003, 40.89],
[1523474234004, 40.93]
]

First, insert the record:

List<List<Object>> pairs = List.of(
List.of(1523474230000L, 39.04),
List.of(1523474231001L, 39.78),
List.of(1523474236006L, 40.07),
List.of(1523474235005L, 41.18),
List.of(1523474233003L, 40.89),
List.of(1523474234004L, 40.93)
);
try (RecordStream rs = session.upsert(key).bin("pairs").setTo(pairs).execute()) {
rs.next().recordOrThrow();
}

Then retrieve the pairs within a specified range of timestamp values using get_by_value_range. The range lower bound is [1523474231000] and upper bound is [1523474234000]. The lower bound is inclusive and the upper bound is exclusive, so the pairs returned are those whose first element is at least 1523474231000 and less than 1523474234000.

try (RecordStream rs = session.query(key)
.bin("pairs").onListValueRange(List.of(1523474231000L), List.of(1523474234000L)).getValues()
.execute()) {
List<?> inRange = rs.next().recordOrThrow().getList("pairs");
// inRange: [[1523474231001, 39.78], [1523474233003, 40.89]]
}