Map operations examples
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Aerospike maps can be used to implement use cases such as:
- Event History Containers
- Document Store
- Leaderboards
Modeling concepts
Nested lists and maps may be combined to model complex use cases. The examples below use the map operations available in each Aerospike language client.
Developers familiar with other NoSQL document stores will see the flexibility in applying map and list operations on bins with nested CDTs. Combined with (operate) single record transactions, Aerospike provides powerful functionality for modeling a wide range of use cases.
Examples
Event containers with unique timestamps
In this example we want to store and query user event data. Each record contains the recent N events of a specific user, keyed by that user’s unique identifier.
Assuming that events will not occur at the same millisecond, we’ll use millisecond timestamps as map keys for distinct events.
Each event’s data will be a tuple [ event-type, { attr1: v1, attr2: v2, ... } ].
Our sample data will be the following events of a single user:
{ 1523474230000: ['fav', {'sku':1, 'b':2}], 1523474231001: ['comment', {'sku':2, 'b':22}], 1523474236006: ['viewed', {'foo':'bar', 'sku':3, 'zz':'top'}], 1523474235005: ['comment', {'sku':1, 'c':1234}], 1523474233003: ['viewed', {'sku':3, 'z':26}], 1523474234004: ['viewed', {'sku':1, 'ff':'hhhl'}]}Retrieving data for specific event types
We’ll retrieve all the events of a specific event type, using a get_all_by_value map operation.
The argument for the operation is the tuple ['comment', *]. The wildcard singleton
(*) matches any remaining elements in the tuple from that position onward,
so all tuples starting with 'comment' as their first element are matched.
// events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
try (RecordStream rs = session.query(key) .bin("events").onMapValue(List.of("comment", SpecialValue.WILDCARD)).getKeysAndValues() .execute()) { Map<?, ?> comments = rs.next().recordOrThrow().getMap("events"); // comments: {1523474231001: ["comment", {b: 22, sku: 2}], // 1523474235005: ["comment", {c: 1234, sku: 1}]}}# events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
from aerospike_sdk import SpecialValue
stream = (session.query(key).bin("events") .on_map_value(["comment", SpecialValue.WILDCARD]).get_keys_and_values() .execute())comments = stream.first_or_raise().record_or_raise().bins["events"]# comments: {1523474231001: ["comment", {"b": 22, "sku": 2}],# 1523474235005: ["comment", {"c": 1234, "sku": 1}]}// events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
// Requires: use aerospike::{operations::maps::{self, MapReturnType}, Value};let record = client.operate(&WritePolicy::default(), &key, &[ maps::get_by_value("events", as_list!("comment", Value::Wildcard), MapReturnType::KeyValue),]).await?;let comments = record.bins.get("events");// comments: [(1523474231001, ["comment", {"b": 22, "sku": 2}]),// (1523474235005, ["comment", {"c": 1234, "sku": 1}])]// events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
IList pattern = new List<Value> { Value.Get("comment"), Value.WILDCARD };Record record = client.Operate(null, key, MapOperation.GetByValue("events", Value.Get(pattern), MapReturnType.KEY_VALUE));IList comments = record.GetList("events");// comments: [(1523474231001, ["comment", {b: 22, sku: 2}]),// (1523474235005, ["comment", {c: 1234, sku: 1}])]// events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
// Requires: import as "github.com/aerospike/aerospike-client-go/v8"pattern := []any{"comment", as.NewWildCardValue()}record, err := client.Operate(nil, key, as.MapGetByValueOp("events", pattern, as.MapReturnType.KEY_VALUE),)comments := record.Bins["events"]// comments: [{1523474231001: ["comment", {b: 22, sku: 2}]},// {1523474235005: ["comment", {c: 1234, sku: 1}]}]// events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
// The Node.js client cannot put a wildcard inside a list value, so this// match has no Node.js form.// events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
as_arraylist pattern;as_arraylist_inita(&pattern, 2);as_arraylist_append_str(&pattern, "comment");as_arraylist_append(&pattern, (as_val*)&as_cmp_wildcard);
as_operations ops;as_operations_inita(&ops, 1);as_operations_map_get_by_value(&ops, "events", NULL, (as_val*)&pattern, AS_MAP_RETURN_KEY_VALUE);
as_record* rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);as_list* comments = as_record_get_list(rec, "events");// comments: [1523474231001, ["comment", {b: 22, sku: 2}],// 1523474235005, ["comment", {c: 1234, sku: 1}]]as_record_destroy(rec);as_operations_destroy(&ops);// events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
List<Value> pattern = Arrays.asList(Value.get("comment"), Value.WILDCARD);Record record = client.operate(null, key, MapOperation.getByValue("events", Value.get(pattern), MapReturnType.KEY_VALUE));List<?> comments = record.getList("events");// comments: [1523474231001=["comment", {b=22, sku=2}],// 1523474235005=["comment", {c=1234, sku=1}]]# events = {1523474230000: ["fav", {sku: 1, b: 2}], ...}
from aerospike_helpers.operations import map_operations
_, _, bins = client.operate(key, [ map_operations.map_get_by_value( "events", ["comment", aerospike.CDTWildcard()], aerospike.MAP_RETURN_KEY_VALUE, )])comments = bins["events"]# comments: [1523474231001, ["comment", {"b": 22, "sku": 2}],# 1523474235005, ["comment", {"c": 1234, "sku": 1}]]Expanding on that example, we will retrieve all the events for multiple event types
using get_all_by_value_list:
try (RecordStream rs = session.query(key) .bin("events").onMapValueList(List.of( List.of("comment", SpecialValue.WILDCARD), List.of("fav", SpecialValue.WILDCARD))) .getKeysAndValues() .execute()) { Map<?, ?> matched = rs.next().recordOrThrow().getMap("events"); // matched: {1523474230000: ["fav", {b: 2, sku: 1}], // 1523474231001: ["comment", {b: 22, sku: 2}], // 1523474235005: ["comment", {c: 1234, sku: 1}]}}wildcard = SpecialValue.WILDCARDstream = (session.query(key).bin("events") .on_map_value_list([["comment", wildcard], ["fav", wildcard]]) .get_keys_and_values() .execute())matched = stream.first_or_raise().record_or_raise().bins["events"]# matched: {1523474230000: ["fav", {"b": 2, "sku": 1}],# 1523474231001: ["comment", {"b": 22, "sku": 2}],# 1523474235005: ["comment", {"c": 1234, "sku": 1}]}let record = client.operate(&WritePolicy::default(), &key, &[ maps::get_by_value_list("events", vec![ as_list!("comment", Value::Wildcard), as_list!("fav", Value::Wildcard), ], MapReturnType::KeyValue),]).await?;let matched = record.bins.get("events");// matched: [(1523474230000, ["fav", {"b": 2, "sku": 1}]),// (1523474231001, ["comment", {"b": 22, "sku": 2}]),// (1523474235005, ["comment", {"c": 1234, "sku": 1}])]IList commentPattern = new List<Value> { Value.Get("comment"), Value.WILDCARD };IList favPattern = new List<Value> { Value.Get("fav"), Value.WILDCARD };
IList patterns = new List<Value> { Value.Get(commentPattern), Value.Get(favPattern) };Record record = client.Operate(null, key, MapOperation.GetByValueList("events", patterns, MapReturnType.KEY_VALUE));IList matched = record.GetList("events");// matched: [(1523474230000, ["fav", {b: 2, sku: 1}]),// (1523474231001, ["comment", {b: 22, sku: 2}]),// (1523474235005, ["comment", {c: 1234, sku: 1}])]// Requires: import as "github.com/aerospike/aerospike-client-go/v8"commentPat := []any{"comment", as.NewWildCardValue()}favPat := []any{"fav", as.NewWildCardValue()}
record, err := client.Operate(nil, key, as.MapGetByValueListOp("events", []any{commentPat, favPat}, as.MapReturnType.KEY_VALUE),)matched := record.Bins["events"]// matched: [{1523474230000: ["fav", {b: 2, sku: 1}]},// {1523474231001: ["comment", {b: 22, sku: 2}]},// {1523474235005: ["comment", {c: 1234, sku: 1}]}]// The Node.js client cannot put a wildcard inside a list value, so this// match has no Node.js form.as_arraylist comment_pat;as_arraylist_inita(&comment_pat, 2);as_arraylist_append_str(&comment_pat, "comment");as_arraylist_append(&comment_pat, (as_val*)&as_cmp_wildcard);
as_arraylist fav_pat;as_arraylist_inita(&fav_pat, 2);as_arraylist_append_str(&fav_pat, "fav");as_arraylist_append(&fav_pat, (as_val*)&as_cmp_wildcard);
as_arraylist patterns;as_arraylist_inita(&patterns, 2);as_arraylist_append(&patterns, (as_val*)&comment_pat);as_arraylist_append(&patterns, (as_val*)&fav_pat);
as_operations ops;as_operations_inita(&ops, 1);as_operations_map_get_by_value_list(&ops, "events", NULL, (as_list*)&patterns, AS_MAP_RETURN_KEY_VALUE);
as_record* rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);as_list* matched = as_record_get_list(rec, "events");// matched: [1523474230000, ["fav", {b: 2, sku: 1}],// 1523474231001, ["comment", {b: 22, sku: 2}],// 1523474235005, ["comment", {c: 1234, sku: 1}]]as_record_destroy(rec);as_operations_destroy(&ops);List<Value> commentPattern = Arrays.asList(Value.get("comment"), Value.WILDCARD);List<Value> favPattern = Arrays.asList(Value.get("fav"), Value.WILDCARD);
List<Value> patterns = Arrays.asList(Value.get(commentPattern), Value.get(favPattern));Record record = client.operate(null, key, MapOperation.getByValueList("events", patterns, MapReturnType.KEY_VALUE));List<?> matched = record.getList("events");// matched: [1523474230000=["fav", {b=2, sku=1}],// 1523474231001=["comment", {b=22, sku=2}],// 1523474235005=["comment", {c=1234, sku=1}]]wildcard = aerospike.CDTWildcard()_, _, bins = client.operate(key, [ map_operations.map_get_by_value_list( "events", [["comment", wildcard], ["fav", wildcard]], aerospike.MAP_RETURN_KEY_VALUE, )])matched = bins["events"]# matched: [1523474230000, ["fav", {"b": 2, "sku": 1}],# 1523474231001, ["comment", {"b": 22, "sku": 2}],# 1523474235005, ["comment", {"c": 1234, "sku": 1}]]Counting events
We will get a count of a specific event type against the sample data above by
specifying a returnType=count:
try (RecordStream rs = session.query(key) .bin("events").onMapValue(List.of("viewed", SpecialValue.WILDCARD)).count() .execute()) { long viewedCount = rs.next().recordOrThrow().getLong("events"); // viewedCount: 3}
try (RecordStream rs = session.query(key) .bin("events").onMapValue(List.of("comment", SpecialValue.WILDCARD)).count() .execute()) { long commentCount = rs.next().recordOrThrow().getLong("events"); // commentCount: 2}stream = (session.query(key).bin("events") .on_map_value(["viewed", SpecialValue.WILDCARD]).count() .execute())viewed_count = stream.first_or_raise().record_or_raise().bins["events"]# viewed_count: 3
stream = (session.query(key).bin("events") .on_map_value(["comment", SpecialValue.WILDCARD]).count() .execute())comment_count = stream.first_or_raise().record_or_raise().bins["events"]# comment_count: 2let record = client.operate(&WritePolicy::default(), &key, &[ maps::get_by_value("events", as_list!("viewed", Value::Wildcard), MapReturnType::Count),]).await?;let viewed_count = record.bins.get("events");// viewed_count: 3
let record = client.operate(&WritePolicy::default(), &key, &[ maps::get_by_value("events", as_list!("comment", Value::Wildcard), MapReturnType::Count),]).await?;let comment_count = record.bins.get("events");// comment_count: 2IList viewedPattern = new List<Value> { Value.Get("viewed"), Value.WILDCARD };Record record = client.Operate(null, key, MapOperation.GetByValue("events", Value.Get(viewedPattern), MapReturnType.COUNT));long viewedCount = record.GetLong("events");// viewedCount: 3
IList commentPattern = new List<Value> { Value.Get("comment"), Value.WILDCARD };record = client.Operate(null, key, MapOperation.GetByValue("events", Value.Get(commentPattern), MapReturnType.COUNT));long commentCount = record.GetLong("events");// commentCount: 2// Requires: import as "github.com/aerospike/aerospike-client-go/v8"viewedPat := []any{"viewed", as.NewWildCardValue()}record, err := client.Operate(nil, key, as.MapGetByValueOp("events", viewedPat, as.MapReturnType.COUNT),)viewedCount := record.Bins["events"]// viewedCount: 3
commentPat := []any{"comment", as.NewWildCardValue()}record, err = client.Operate(nil, key, as.MapGetByValueOp("events", commentPat, as.MapReturnType.COUNT),)commentCount := record.Bins["events"]// commentCount: 2// The Node.js client cannot put a wildcard inside a list value, so this// match has no Node.js form.as_arraylist viewed_pat;as_arraylist_inita(&viewed_pat, 2);as_arraylist_append_str(&viewed_pat, "viewed");as_arraylist_append(&viewed_pat, (as_val*)&as_cmp_wildcard);
as_operations ops;as_operations_inita(&ops, 1);as_operations_map_get_by_value(&ops, "events", NULL, (as_val*)&viewed_pat, AS_MAP_RETURN_COUNT);
as_record* rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);int64_t viewed_count = as_record_get_int64(rec, "events", 0);// viewed_count: 3as_record_destroy(rec);as_operations_destroy(&ops);
as_arraylist comment_pat;as_arraylist_inita(&comment_pat, 2);as_arraylist_append_str(&comment_pat, "comment");as_arraylist_append(&comment_pat, (as_val*)&as_cmp_wildcard);
as_operations ops2;as_operations_inita(&ops2, 1);as_operations_map_get_by_value(&ops2, "events", NULL, (as_val*)&comment_pat, AS_MAP_RETURN_COUNT);
as_record* rec2 = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops2, &rec2);int64_t comment_count = as_record_get_int64(rec2, "events", 0);// comment_count: 2as_record_destroy(rec2);as_operations_destroy(&ops2);List<Value> viewedPattern = Arrays.asList(Value.get("viewed"), Value.WILDCARD);Record record = client.operate(null, key, MapOperation.getByValue("events", Value.get(viewedPattern), MapReturnType.COUNT));long viewedCount = record.getLong("events");// viewedCount: 3
List<Value> commentPattern = Arrays.asList(Value.get("comment"), Value.WILDCARD);record = client.operate(null, key, MapOperation.getByValue("events", Value.get(commentPattern), MapReturnType.COUNT));long commentCount = record.getLong("events");// commentCount: 2wildcard = aerospike.CDTWildcard()
_, _, bins = client.operate(key, [ map_operations.map_get_by_value( "events", ["viewed", wildcard], aerospike.MAP_RETURN_COUNT )])viewed_count = bins["events"]# viewed_count: 3
_, _, bins = client.operate(key, [ map_operations.map_get_by_value( "events", ["comment", wildcard], aerospike.MAP_RETURN_COUNT )])comment_count = bins["events"]# comment_count: 2Trimming the map
Often we want to cap the number of events captured within a map. We will use
the remove_by_index_range
map operation to keep the last 1000 events. The INVERTED flag removes everything
outside the specified range — effectively keeping only the 1000 highest-indexed
(most recent) entries and discarding the rest.
try (RecordStream rs = session.upsert(key) .bin("events").onMapIndexRange(-1000, 1000).removeAllOthers() .execute()) { rs.next().recordOrThrow();}// The sample holds 6 events, fewer than 1000, so none are removed.stream = (session.upsert(key) .bin("events").on_map_index_range(-1000, 1000).remove_all_others() .execute())stream.first_or_raise().record_or_raise()# The sample holds 6 events, fewer than 1000, so none are removed.// Requires: use aerospike::operations::maps::{self, InvertedMapReturn, MapReturnType};client.operate(&WritePolicy::default(), &key, &[ maps::remove_by_index_range("events", -1000, 1000, InvertedMapReturn(MapReturnType::None)),]).await?;// The sample holds 6 events, fewer than 1000, so none are removed.client.Operate(null, key, MapOperation.RemoveByIndexRange("events", -1000, 1000, MapReturnType.NONE | MapReturnType.INVERTED));// The sample holds 6 events, fewer than 1000, so none are removed.// Requires: import as "github.com/aerospike/aerospike-client-go/v8"_, err := client.Operate(nil, key, as.MapRemoveByIndexRangeCountOp("events", -1000, 1000, as.MapReturnType.NONE|as.MapReturnType.INVERTED),)// The sample holds 6 events, fewer than 1000, so none are removed.const Aerospike = await import("aerospike");const maps = Aerospike.maps;
await client.operate(key, [ maps.removeByIndexRange('events', -1000, 1000, maps.returnType.NONE | maps.returnType.INVERTED),])// The sample holds 6 events, fewer than 1000, so none are removed.as_operations ops;as_operations_inita(&ops, 1);as_operations_map_remove_by_index_range(&ops, "events", NULL, -1000, 1000, AS_MAP_RETURN_NONE | AS_MAP_RETURN_INVERTED);
aerospike_key_operate(&as, &err, NULL, &key, &ops, NULL);// The sample holds 6 events, fewer than 1000, so none are removed.as_operations_destroy(&ops);client.operate(null, key, MapOperation.removeByIndexRange("events", -1000, 1000, MapReturnType.NONE | MapReturnType.INVERTED));// The sample holds 6 events, fewer than 1000, so none are removed.client.operate(key, [ map_operations.map_remove_by_index_range( "events", -1000, 1000, aerospike.MAP_RETURN_NONE, inverted=True )])# The sample holds 6 events, fewer than 1000, so none are removed.Event containers with unique UUIDs
In some use cases a timestamp would result in frequent collisions. We can model using a unique identifier as the map key.
In this example a conversation thread is stored in a single record. The map keys
are message UUIDs, and the map values are list tuples [timestamp, msg-string, username].
Our sample data will be the messages in a single conversation thread:
{ '0edf5b73-535c-4be7-b653-c0513dc79fb4': [1523474230, "Billie Jean is not my lover", "MJ"], '29342a0b-e20f-4676-9ecf-dfdf02ef6683': [1523474241, "She's just a girl who", "MJ"], '31a8ba1b-8415-aab7-0ecc-56ee659f0a83': [1523474245, "claims that I am the one", "MJ"], '9f54b4f8-992e-427f-9fb3-e63348cd6ac9': [1523474249, "...", "Tito"], '1ae56b18-7a3c-4f64-adb7-2e845eb5094e': [1523474257, "But the kid is not my son", "MJ"], '08785e96-eb1b-4a74-a767-7b56e8f13ea9': [1523474306, "ok...", "Tito"], '319fa1a6-0640-4354-a426-10c4d3459f0a': [1523474316, "Hee-hee!", "MJ"]}We will retrieve all the messages in a range of timestamps, using the get_by_value_interval map operation.
The arguments for the operation are minimum and maximum tuples of [timestamp, nil]. The NIL singleton is lower in value than a string. The get_by_value_interval checks if each map value (a list) is between the two list arguments of the operation.
// Retrieve messages with timestamps in [1523474240, 1523474246)try (RecordStream rs = session.query(key) .bin("msgs").onMapValueRange(Arrays.asList(1523474240, null), Arrays.asList(1523474246, null)) .getKeysAndValues() .execute()) { Map<?, ?> inRange = rs.next().recordOrThrow().getMap("msgs"); // inRange: {"29342a0b-...": [1523474241, "She's just a girl who", "MJ"], // "31a8ba1b-...": [1523474245, "claims that I am the one", "MJ"]}}# Retrieve messages with timestamps in [1523474240, 1523474246)stream = (session.query(key).bin("msgs") .on_map_value_range([1523474240, None], [1523474246, None]) .get_keys_and_values() .execute())in_range = stream.first_or_raise().record_or_raise().bins["msgs"]# in_range: {"29342a0b-...": [1523474241, "She's just a girl who", "MJ"],# "31a8ba1b-...": [1523474245, "claims that I am the one", "MJ"]}// Retrieve messages with timestamps in [1523474240, 1523474246)let record = client.operate(&WritePolicy::default(), &key, &[ maps::get_by_value_range("msgs", as_list!(1523474240, Value::Nil), as_list!(1523474246, Value::Nil), MapReturnType::KeyValue),]).await?;let in_range = record.bins.get("msgs");// in_range: [("29342a0b-...", [1523474241, "She's just a girl who", "MJ"]),// ("31a8ba1b-...", [1523474245, "claims that I am the one", "MJ"])]// Retrieve messages with timestamps in [1523474240, 1523474246)IList rangeStart = new List<Value> { Value.Get(1523474240), Value.AsNull };IList rangeEnd = new List<Value> { Value.Get(1523474246), Value.AsNull };
Record record = client.Operate(null, key, MapOperation.GetByValueRange("msgs", Value.Get(rangeStart), Value.Get(rangeEnd), MapReturnType.KEY_VALUE));IList inRange = record.GetList("msgs");// inRange: [("29342a0b-...", [1523474241, "She's just a girl who", "MJ"]),// ("31a8ba1b-...", [1523474245, "claims that I am the one", "MJ"])]// Requires: import as "github.com/aerospike/aerospike-client-go/v8"// Retrieve messages with timestamps in [1523474240, 1523474246)rangeStart := []any{1523474240, nil}rangeEnd := []any{1523474246, nil}
record, err := client.Operate(nil, key, as.MapGetByValueRangeOp("msgs", rangeStart, rangeEnd, as.MapReturnType.KEY_VALUE),)inRange := record.Bins["msgs"]// inRange: [{"29342a0b-...": [1523474241, "She's just a girl who", "MJ"]},// {"31a8ba1b-...": [1523474245, "claims that I am the one", "MJ"]}]// Retrieve messages with timestamps in [1523474240, 1523474246)const result = await client.operate(key, [ maps.getByValueRange('msgs', [1523474240, null], [1523474246, null], maps.returnType.KEY_VALUE),])const inRange = result.bins.msgs// inRange: ["29342a0b-...", [1523474241, "She's just a girl who", "MJ"],// "31a8ba1b-...", [1523474245, "claims that I am the one", "MJ"]]// Retrieve messages with timestamps in [1523474240, 1523474246)as_arraylist range_start;as_arraylist_inita(&range_start, 2);as_arraylist_append_int64(&range_start, 1523474240);as_arraylist_append(&range_start, (as_val*)&as_nil);
as_arraylist range_end;as_arraylist_inita(&range_end, 2);as_arraylist_append_int64(&range_end, 1523474246);as_arraylist_append(&range_end, (as_val*)&as_nil);
as_operations ops;as_operations_inita(&ops, 1);as_operations_map_get_by_value_range(&ops, "msgs", NULL, (as_val*)&range_start, (as_val*)&range_end, AS_MAP_RETURN_KEY_VALUE);
as_record* rec = NULL;aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);as_list* in_range = as_record_get_list(rec, "msgs");// in_range: ["29342a0b-...", [1523474241, "She's just a girl who", "MJ"],// "31a8ba1b-...", [1523474245, "claims that I am the one", "MJ"]]as_record_destroy(rec);as_operations_destroy(&ops);// Retrieve messages with timestamps in [1523474240, 1523474246)List<Value> rangeStart = Arrays.asList(Value.get(1523474240), Value.getAsNull());List<Value> rangeEnd = Arrays.asList(Value.get(1523474246), Value.getAsNull());
Record record = client.operate(null, key, MapOperation.getByValueRange("msgs", Value.get(rangeStart), Value.get(rangeEnd), MapReturnType.KEY_VALUE));List<?> inRange = record.getList("msgs");// inRange: ["29342a0b-..."=[1523474241, "She's just a girl who", "MJ"],// "31a8ba1b-..."=[1523474245, "claims that I am the one", "MJ"]]# Retrieve messages with timestamps in [1523474240, 1523474246)_, _, bins = client.operate(key, [ map_operations.map_get_by_value_range( "msgs", [1523474240, None], [1523474246, None], aerospike.MAP_RETURN_KEY_VALUE, )])in_range = bins["msgs"]# in_range: ["29342a0b-...", [1523474241, "She's just a girl who", "MJ"],# "31a8ba1b-...", [1523474245, "claims that I am the one", "MJ"]]By the interval comparison rules the following is evaluated:
[1523474240, nil] ≰ [1523474230, "Billie Jean is not my lover", "MJ"] < [1523474246, nil] (false)[1523474240, nil] ≤ [1523474241, "She's just a girl who", "MJ"] < [1523474246, nil] (true)[1523474240, nil] ≤ [1523474245, "claims that I am the one", "MJ"] < [1523474246, nil] (true)[1523474240, nil] ≤ [1523474249, "...", "Tito"] ≮ [1523474246, nil] (false)[1523474240, nil] ≤ [1523474257, "But the kid is not my son", "MJ"] ≮ [1523474246, nil] (false)[1523474240, nil] ≤ [1523474306, "ok...", "Tito"] ≮ [1523474246, nil] (false)[1523474240, nil] ≤ [1523474316, "Hee-hee!", "MJ"] ≮ [1523474246, nil] (false)