Map indexes and querying
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Overview
This page describes how to create a secondary index on bins where the data type is a map. You can index either map key or map value.
Indexing on Map elements
- Similar to basic indexing, the indexable map data types are numeric, string, and GeoJSON.
- You can index a Map at any depth, up to the 64-level CDT nesting limit (Database 8.2.0 and later). Prior to Database 6.1.0, Map indexing was only on the top-level element, not nested elements.
- When creating index, specify explicitly that map bins should be indexed, and what data type to index on.
- When querying, specify that query should be applied on a CDT data type.
- Similar to basic querying, equality, range for integer and string data types, points-within-region, and region-containing-points for GeoJSON data type are supported.
Examples
The following examples use asadm. For index management options, see Secondary index queries.
Create an index with source type mapkeys and a String data type:
Admin+> manage sindex create string foo_mapkey_idx in mapkeys ns test set demo bin fooCreate an index with source type mapvalues and an integer data type:
Admin+> manage sindex create integer foo_mapval_idx in mapvalues ns test set demo bin fooUse show sindex to confirm the indexes were created successfully. Current versions of asadm display integer in the Bin Type column; older versions display numeric.
Admin+> show sindex~~~~~~~~~~~~~~~~~~~Secondary Indexes (2026-04-08 16:01:35 UTC)~~~~~~~~~~~~~~~~~~~ Index Name|Namespace| Set|Bin| Bin| Index|State | | | | Type| Type|foo_mapkey_idx|test |demo|foo|string |mapkeys |RWfoo_mapval_idx|test |demo|foo|integer|mapvalues|RWNumber of rows: 2Elements of the indexed map are type checked, so a record whose foo bin
contains { a:1, b:"2", c:3, d:[4], e:5, 666:"zzz" } results in the following indexing:
| Index On | Key Type | Index Type | Eligible Secondary Index Key |
|---|---|---|---|
| foo | string | MAPKEYS | a, b, c, d, e |
| foo | integer | MAPVALUES | 1, 3, 5 |
Map index queries
This example inserts records with a foo map bin containing mixed key-value types, then queries by map key and map value using the indexes created above.
Insert data
import com.aerospike.client.sdk.Cluster;import com.aerospike.client.sdk.ClusterDefinition;import com.aerospike.client.sdk.DataSet;import com.aerospike.client.sdk.Session;import com.aerospike.client.sdk.policy.Behavior;import java.util.Map;
Cluster cluster = new ClusterDefinition("127.0.0.1", 3000).connect();Session session = cluster.createSession(Behavior.DEFAULT);DataSet demo = DataSet.of("test", "demo");
session.upsert(demo.id("u1")) .bin("username").setTo("Bob Roberts") .bin("foo").setTo(Map.of("a", 1, "b", "2", "c", 3)) .execute();
session.upsert(demo.id("u2")) .bin("username").setTo("rocketbob") .bin("foo").setTo(Map.of("c", 3, "e", 5)) .execute();
session.upsert(demo.id("u3")) .bin("username").setTo("samunwise") .bin("foo").setTo(Map.of("x", Map.of("z", 26), "y", "yyy")) .execute();from aerospike_sdk import Behavior, DataSetfrom aerospike_sdk.sync import ClusterDefinition
cluster = ClusterDefinition("127.0.0.1", 3000).connect()session = cluster.create_session(Behavior.DEFAULT)demo = DataSet.of("test", "demo")
session.upsert(demo.id("u1")).put({ "username": "Bob Roberts", "foo": {"a": 1, "b": "2", "c": 3},}).execute()
session.upsert(demo.id("u2")).put({ "username": "rocketbob", "foo": {"c": 3, "e": 5},}).execute()
session.upsert(demo.id("u3")).put({ "username": "samunwise", "foo": {"x": {"z": 26}, "y": "yyy"},}).execute()use aerospike::{as_bin, as_map, as_val, Client, ClientPolicy, Key, WritePolicy};
let client = Client::new(&ClientPolicy::default(), &"127.0.0.1:3000").await?;
let key1 = Key::new("test", "demo", as_val!("u1"))?;client.put(&WritePolicy::default(), &key1, &[ as_bin!("username", "Bob Roberts"), as_bin!("foo", as_map!("a" => 1, "b" => "2", "c" => 3)),]).await?;
let key2 = Key::new("test", "demo", as_val!("u2"))?;client.put(&WritePolicy::default(), &key2, &[ as_bin!("username", "rocketbob"), as_bin!("foo", as_map!("c" => 3, "e" => 5)),]).await?;
let key3 = Key::new("test", "demo", as_val!("u3"))?;client.put(&WritePolicy::default(), &key3, &[ as_bin!("username", "samunwise"), as_bin!("foo", as_map!("x" => as_map!("z" => 26), "y" => "yyy")),]).await?;using System.Collections.Generic;using Aerospike.Client;
AerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
Key key1 = new Key("test", "demo", "u1");Dictionary<string, object> cart1 = new(){ ["a"] = 1L, ["b"] = "2", ["c"] = 3L,};client.Put(null, key1, new Bin("username", "Bob Roberts"), new Bin("foo", cart1));
Key key2 = new Key("test", "demo", "u2");Dictionary<string, object> cart2 = new(){ ["c"] = 3L, ["e"] = 5L,};client.Put(null, key2, new Bin("username", "rocketbob"), new Bin("foo", cart2));
Key key3 = new Key("test", "demo", "u3");Dictionary<string, object> cart3 = new(){ ["x"] = new Dictionary<string, object> { ["z"] = 26L }, ["y"] = "yyy",};client.Put(null, key3, new Bin("username", "samunwise"), new Bin("foo", cart3));import ( as "github.com/aerospike/aerospike-client-go/v8")
client, _ := as.NewClient("127.0.0.1", 3000)
key1, _ := as.NewKey("test", "demo", "u1")client.PutBins(nil, key1, as.NewBin("username", "Bob Roberts"), as.NewBin("foo", map[interface{}]interface{}{"a": 1, "b": "2", "c": 3}),)
key2, _ := as.NewKey("test", "demo", "u2")client.PutBins(nil, key2, as.NewBin("username", "rocketbob"), as.NewBin("foo", map[interface{}]interface{}{"c": 3, "e": 5}),)
key3, _ := as.NewKey("test", "demo", "u3")client.PutBins(nil, key3, as.NewBin("username", "samunwise"), as.NewBin("foo", map[interface{}]interface{}{ "x": map[interface{}]interface{}{"z": 26}, "y": "yyy", }),)const Aerospike = await import("aerospike");
const client = await Aerospike.connect({ hosts: '127.0.0.1:3000' })
const key1 = new Aerospike.Key('test', 'demo', 'u1')await client.put(key1, { username: 'Bob Roberts', foo: { a: 1, b: '2', c: 3 },})
const key2 = new Aerospike.Key('test', 'demo', 'u2')await client.put(key2, { username: 'rocketbob', foo: { c: 3, e: 5 },})
const key3 = new Aerospike.Key('test', 'demo', 'u3')await client.put(key3, { username: 'samunwise', foo: { x: { z: 26 }, y: 'yyy' },})#include <aerospike/aerospike.h>#include <aerospike/aerospike_key.h>#include <aerospike/as_hashmap.h>#include <aerospike/as_record.h>#include <aerospike/as_stringmap.h>
as_config config;as_config_init(&config);as_config_add_host(&config, "127.0.0.1", 3000);aerospike as;aerospike_init(&as, &config);as_error err;aerospike_connect(&as, &err);
as_key key1;as_key_init_str(&key1, "test", "demo", "u1");as_hashmap cart1;as_hashmap_init(&cart1, 3);as_stringmap_set_int64((as_map*)&cart1, "a", 1);as_stringmap_set_str((as_map*)&cart1, "b", "2");as_stringmap_set_int64((as_map*)&cart1, "c", 3);as_record rec1;as_record_inita(&rec1, 2);as_record_set_str(&rec1, "username", "Bob Roberts");as_record_set_map(&rec1, "foo", (as_map*)&cart1);aerospike_key_put(&as, &err, NULL, &key1, &rec1);as_record_destroy(&rec1);
as_key key2;as_key_init_str(&key2, "test", "demo", "u2");as_hashmap cart2;as_hashmap_init(&cart2, 2);as_stringmap_set_int64((as_map*)&cart2, "c", 3);as_stringmap_set_int64((as_map*)&cart2, "e", 5);as_record rec2;as_record_inita(&rec2, 2);as_record_set_str(&rec2, "username", "rocketbob");as_record_set_map(&rec2, "foo", (as_map*)&cart2);aerospike_key_put(&as, &err, NULL, &key2, &rec2);as_record_destroy(&rec2);
as_key key3;as_key_init_str(&key3, "test", "demo", "u3");as_hashmap inner;as_hashmap_init(&inner, 1);as_stringmap_set_int64((as_map*)&inner, "z", 26);as_hashmap cart3;as_hashmap_init(&cart3, 2);as_stringmap_set((as_map*)&cart3, "x", (as_val*)&inner);as_stringmap_set_str((as_map*)&cart3, "y", "yyy");as_record rec3;as_record_inita(&rec3, 2);as_record_set_str(&rec3, "username", "samunwise");as_record_set_map(&rec3, "foo", (as_map*)&cart3);aerospike_key_put(&as, &err, NULL, &key3, &rec3);as_record_destroy(&rec3);import com.aerospike.client.AerospikeClient;import com.aerospike.client.Bin;import com.aerospike.client.Key;import java.util.HashMap;import java.util.Map;
AerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
Key key1 = new Key("test", "demo", "u1");Map<String, Object> cart1 = new HashMap<>();cart1.put("a", 1);cart1.put("b", "2");cart1.put("c", 3);client.put(null, key1, new Bin("username", "Bob Roberts"), new Bin("foo", cart1));
Key key2 = new Key("test", "demo", "u2");Map<String, Object> cart2 = new HashMap<>();cart2.put("c", 3);cart2.put("e", 5);client.put(null, key2, new Bin("username", "rocketbob"), new Bin("foo", cart2));
Key key3 = new Key("test", "demo", "u3");Map<String, Object> cart3 = new HashMap<>();cart3.put("x", new HashMap<>(Map.of("z", 26)));cart3.put("y", "yyy");client.put(null, key3, new Bin("username", "samunwise"), new Bin("foo", cart3));import aerospike
client = aerospike.client({"hosts": [("127.0.0.1", 3000)]}).connect()
key1 = ("test", "demo", "u1")client.put(key1, { "username": "Bob Roberts", "foo": {"a": 1, "b": "2", "c": 3},})
key2 = ("test", "demo", "u2")client.put(key2, { "username": "rocketbob", "foo": {"c": 3, "e": 5},})
key3 = ("test", "demo", "u3")client.put(key3, { "username": "samunwise", "foo": {"x": {"z": 26}, "y": "yyy"},})Query by map value (integer equality)
Query foo_mapval_idx for records where the foo map contains a value equal to 1.
Only records with a matching integer value are returned. b: "2" is a string, not an integer, so it does not match.
import com.aerospike.client.sdk.RecordStream;
try (RecordStream rs = session.query(demo).where("$.foo.{=1}.exists()").execute()) { rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));}// Output: Bob Robertsfor row in session.query(demo).where("$.foo.{=1}.exists()").execute(): print(row.record_or_raise().bins["username"])# Output: Bob Robertsuse aerospike::{query::Filter, Bins, CollectionIndexType, PartitionFilter, QueryPolicy, Statement};use futures::StreamExt;
let mut stmt = Statement::new("test", "demo", Bins::All);stmt.add_filter(Filter::contains("foo", 1, CollectionIndexType::MapValues));let mut rs = client.query(&QueryPolicy::default(), PartitionFilter::all(), stmt) .await?.into_stream();while let Some(rec) = rs.next().await { println!("{}", rec?.bins["username"]);}// Output: Bob RobertsStatement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("demo");stmt.SetFilter(Filter.Contains("foo", IndexCollectionType.MAPVALUES, 1L));
RecordSet rs = client.Query(null, stmt);while (rs.Next()) { Console.WriteLine(rs.Record.GetString("username"));}rs.Close();// Output: Bob Robertsimport ( "fmt")
stmt := as.NewStatement("test", "demo")stmt.SetFilter(as.NewContainsFilter("foo", as.ICT_MAPVALUES, 1))rs, _ := client.Query(nil, stmt)for rec := range rs.Results() { fmt.Println(rec.Record.Bins["username"])}// Output: Bob Robertsconst filter = Aerospike.filter;
const query = client.query('test', 'demo')query.where(filter.contains('foo', 1, Aerospike.indexType.MAPVALUES))for (const rec of await query.results()) { console.log(rec.bins.username)}// Output: Bob Roberts#include <stdio.h>#include <aerospike/aerospike_query.h>#include <aerospike/as_query.h>
bool query_cb(const as_val* val, void* udata) { if (!val) return false; as_record* rec = as_record_fromval(val); printf("%s\n", as_record_get_str(rec, "username")); return true;}
as_query q;as_query_init(&q, "test", "demo");as_query_where_inita(&q, 1);as_query_where(&q, "foo", as_contains(MAPVALUES, INTEGER, (int64_t)1));aerospike_query_foreach(&as, &err, NULL, &q, query_cb, NULL);as_query_destroy(&q);// Output: Bob Robertsimport com.aerospike.client.query.Filter;import com.aerospike.client.query.IndexCollectionType;import com.aerospike.client.query.RecordSet;import com.aerospike.client.query.Statement;
Statement stmt = new Statement();stmt.setNamespace("test");stmt.setSetName("demo");stmt.setFilter(Filter.contains("foo", IndexCollectionType.MAPVALUES, 1));
RecordSet rs = client.query(null, stmt);while (rs.next()) { System.out.println(rs.getRecord().getString("username"));}rs.close();// Output: Bob Robertsfrom aerospike import predicates as p
query = client.query("test", "demo")query.where(p.contains("foo", aerospike.INDEX_TYPE_MAPVALUES, 1))for _, _, record in query.results(): print(record["username"])# Output: Bob RobertsQuery by map value (integer equality, multiple matches)
Query for records where the foo map contains a value equal to 3.
Both u1 (c: 3) and u2 (c: 3) match.
try (RecordStream rs = session.query(demo).where("$.foo.{=3}.exists()").execute()) { rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));}// Output, in no guaranteed order:// Bob Roberts// rocketbobfor row in session.query(demo).where("$.foo.{=3}.exists()").execute(): print(row.record_or_raise().bins["username"])# Output, in no guaranteed order:# Bob Roberts# rocketboblet mut stmt = Statement::new("test", "demo", Bins::All);stmt.add_filter(Filter::contains("foo", 3, CollectionIndexType::MapValues));let mut rs = client.query(&QueryPolicy::default(), PartitionFilter::all(), stmt) .await?.into_stream();while let Some(rec) = rs.next().await { println!("{}", rec?.bins["username"]);}// Output, in no guaranteed order:// Bob Roberts// rocketbobStatement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("demo");stmt.SetFilter(Filter.Contains("foo", IndexCollectionType.MAPVALUES, 3L));
RecordSet rs = client.Query(null, stmt);while (rs.Next()) { Console.WriteLine(rs.Record.GetString("username"));}rs.Close();// Output, in no guaranteed order:// Bob Roberts// rocketbob// Requires: import as "github.com/aerospike/aerospike-client-go/v8"stmt := as.NewStatement("test", "demo")stmt.SetFilter(as.NewContainsFilter("foo", as.ICT_MAPVALUES, 3))rs, _ := client.Query(nil, stmt)for rec := range rs.Results() { fmt.Println(rec.Record.Bins["username"])}// Output, in no guaranteed order:// Bob Roberts// rocketbobconst query = client.query('test', 'demo')query.where(filter.contains('foo', 3, Aerospike.indexType.MAPVALUES))for (const rec of await query.results()) { console.log(rec.bins.username)}// Output, in no guaranteed order:// Bob Roberts// rocketbobas_query q;as_query_init(&q, "test", "demo");as_query_where_inita(&q, 1);as_query_where(&q, "foo", as_contains(MAPVALUES, INTEGER, (int64_t)3));aerospike_query_foreach(&as, &err, NULL, &q, query_cb, NULL);as_query_destroy(&q);// Output, in no guaranteed order:// Bob Roberts// rocketbobStatement stmt = new Statement();stmt.setNamespace("test");stmt.setSetName("demo");stmt.setFilter(Filter.contains("foo", IndexCollectionType.MAPVALUES, 3));
RecordSet rs = client.query(null, stmt);while (rs.next()) { System.out.println(rs.getRecord().getString("username"));}rs.close();// Output, in no guaranteed order:// Bob Roberts// rocketbobquery = client.query("test", "demo")query.where(p.contains("foo", aerospike.INDEX_TYPE_MAPVALUES, 3))for _, _, record in query.results(): print(record["username"])# Output, in no guaranteed order:# Bob Roberts# rocketbobQuery by map value (integer range)
Query foo_mapval_idx for records where the foo map contains any integer value in the range [1, 5].
Every matching record is returned at least once. A record whose map holds more than one value in the range can be returned more than once, so your application must handle deduplication (see Known limitations).
// AEL value ranges exclude the upper bound, so 1:6 covers 1 through 5.try (RecordStream rs = session.query(demo).where("$.foo.{=1:6}.exists()").execute()) { rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));}// Output, in no guaranteed order:// Bob Roberts// rocketbob# AEL value ranges exclude the upper bound, so 1:6 covers 1 through 5.for row in session.query(demo).where("$.foo.{=1:6}.exists()").execute(): print(row.record_or_raise().bins["username"])# Output, in no guaranteed order:# Bob Roberts# rocketboblet mut stmt = Statement::new("test", "demo", Bins::All);stmt.add_filter(Filter::contains_range("foo", 1, 5, CollectionIndexType::MapValues));let mut rs = client.query(&QueryPolicy::default(), PartitionFilter::all(), stmt) .await?.into_stream();while let Some(rec) = rs.next().await { println!("{}", rec?.bins["username"]);}// Output, in no guaranteed order:// Bob Roberts// rocketbobStatement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("demo");stmt.SetFilter(Filter.Range("foo", IndexCollectionType.MAPVALUES, 1L, 5L));
RecordSet rs = client.Query(null, stmt);while (rs.Next()) { Console.WriteLine(rs.Record.GetString("username"));}rs.Close();// Output, in no guaranteed order:// Bob Roberts// rocketbob// Requires: import as "github.com/aerospike/aerospike-client-go/v8"stmt := as.NewStatement("test", "demo")stmt.SetFilter(as.NewContainsRangeFilter("foo", as.ICT_MAPVALUES, 1, 5))rs, _ := client.Query(nil, stmt)for rec := range rs.Results() { fmt.Println(rec.Record.Bins["username"])}// Output, in no guaranteed order:// Bob Roberts// rocketbobconst query = client.query('test', 'demo')query.where(filter.range('foo', 1, 5, Aerospike.indexType.MAPVALUES))for (const rec of await query.results()) { console.log(rec.bins.username)}// Output, in no guaranteed order:// Bob Roberts// rocketbobas_query q;as_query_init(&q, "test", "demo");as_query_where_inita(&q, 1);as_query_where(&q, "foo", as_range(MAPVALUES, INTEGER, (int64_t)1, (int64_t)5));aerospike_query_foreach(&as, &err, NULL, &q, query_cb, NULL);as_query_destroy(&q);// Output, in no guaranteed order:// Bob Roberts// rocketbobStatement stmt = new Statement();stmt.setNamespace("test");stmt.setSetName("demo");stmt.setFilter(Filter.range("foo", IndexCollectionType.MAPVALUES, 1, 5));
RecordSet rs = client.query(null, stmt);while (rs.next()) { System.out.println(rs.getRecord().getString("username"));}rs.close();// Output, in no guaranteed order:// Bob Roberts// rocketbobquery = client.query("test", "demo")query.where(p.range("foo", aerospike.INDEX_TYPE_MAPVALUES, 1, 5))for _, _, record in query.results(): print(record["username"])# Output, in no guaranteed order:# Bob Roberts# rocketbobQuery by map key (string equality)
Query foo_mapkey_idx for records where the foo map contains the key "y".
try (RecordStream rs = session.query(demo).where("$.foo.{@'y'}.exists()").execute()) { rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));}// Output: samunwisefor row in session.query(demo).where("$.foo.{@'y'}.exists()").execute(): print(row.record_or_raise().bins["username"])# Output: samunwiselet mut stmt = Statement::new("test", "demo", Bins::All);stmt.add_filter(Filter::contains("foo", "y", CollectionIndexType::MapKeys));let mut rs = client.query(&QueryPolicy::default(), PartitionFilter::all(), stmt) .await?.into_stream();while let Some(rec) = rs.next().await { println!("{}", rec?.bins["username"]);}// Output: samunwiseStatement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("demo");stmt.SetFilter(Filter.Contains("foo", IndexCollectionType.MAPKEYS, "y"));
RecordSet rs = client.Query(null, stmt);while (rs.Next()) { Console.WriteLine(rs.Record.GetString("username"));}rs.Close();// Output: samunwise// Requires: import as "github.com/aerospike/aerospike-client-go/v8"stmt := as.NewStatement("test", "demo")stmt.SetFilter(as.NewContainsFilter("foo", as.ICT_MAPKEYS, "y"))rs, _ := client.Query(nil, stmt)for rec := range rs.Results() { fmt.Println(rec.Record.Bins["username"])}// Output: samunwiseconst query = client.query('test', 'demo')query.where(filter.contains('foo', 'y', Aerospike.indexType.MAPKEYS))for (const rec of await query.results()) { console.log(rec.bins.username)}// Output: samunwiseas_query q;as_query_init(&q, "test", "demo");as_query_where_inita(&q, 1);as_query_where(&q, "foo", as_contains(MAPKEYS, STRING, "y"));aerospike_query_foreach(&as, &err, NULL, &q, query_cb, NULL);as_query_destroy(&q);// Output: samunwiseStatement stmt = new Statement();stmt.setNamespace("test");stmt.setSetName("demo");stmt.setFilter(Filter.contains("foo", IndexCollectionType.MAPKEYS, "y"));
RecordSet rs = client.query(null, stmt);while (rs.next()) { System.out.println(rs.getRecord().getString("username"));}rs.close();// Output: samunwisequery = client.query("test", "demo")query.where(p.contains("foo", aerospike.INDEX_TYPE_MAPKEYS, "y"))for _, _, record in query.results(): print(record["username"])# Output: samunwiseQuery by map key (multiple matches)
Query for records where the foo map contains the key "c".
Both u1 and u2 have a "c" key.
try (RecordStream rs = session.query(demo).where("$.foo.{@'c'}.exists()").execute()) { rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));}// Output, in no guaranteed order:// Bob Roberts// rocketbobfor row in session.query(demo).where("$.foo.{@'c'}.exists()").execute(): print(row.record_or_raise().bins["username"])# Output, in no guaranteed order:# Bob Roberts# rocketboblet mut stmt = Statement::new("test", "demo", Bins::All);stmt.add_filter(Filter::contains("foo", "c", CollectionIndexType::MapKeys));let mut rs = client.query(&QueryPolicy::default(), PartitionFilter::all(), stmt) .await?.into_stream();while let Some(rec) = rs.next().await { println!("{}", rec?.bins["username"]);}// Output, in no guaranteed order:// Bob Roberts// rocketbobStatement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("demo");stmt.SetFilter(Filter.Contains("foo", IndexCollectionType.MAPKEYS, "c"));
RecordSet rs = client.Query(null, stmt);while (rs.Next()) { Console.WriteLine(rs.Record.GetString("username"));}rs.Close();// Output, in no guaranteed order:// Bob Roberts// rocketbob// Requires: import as "github.com/aerospike/aerospike-client-go/v8"stmt := as.NewStatement("test", "demo")stmt.SetFilter(as.NewContainsFilter("foo", as.ICT_MAPKEYS, "c"))rs, _ := client.Query(nil, stmt)for rec := range rs.Results() { fmt.Println(rec.Record.Bins["username"])}// Output, in no guaranteed order:// Bob Roberts// rocketbobconst query = client.query('test', 'demo')query.where(filter.contains('foo', 'c', Aerospike.indexType.MAPKEYS))for (const rec of await query.results()) { console.log(rec.bins.username)}// Output, in no guaranteed order:// Bob Roberts// rocketbobas_query q;as_query_init(&q, "test", "demo");as_query_where_inita(&q, 1);as_query_where(&q, "foo", as_contains(MAPKEYS, STRING, "c"));aerospike_query_foreach(&as, &err, NULL, &q, query_cb, NULL);as_query_destroy(&q);// Output, in no guaranteed order:// Bob Roberts// rocketbobStatement stmt = new Statement();stmt.setNamespace("test");stmt.setSetName("demo");stmt.setFilter(Filter.contains("foo", IndexCollectionType.MAPKEYS, "c"));
RecordSet rs = client.query(null, stmt);while (rs.next()) { System.out.println(rs.getRecord().getString("username"));}rs.close();// Output, in no guaranteed order:// Bob Roberts// rocketbobquery = client.query("test", "demo")query.where(p.contains("foo", aerospike.INDEX_TYPE_MAPKEYS, "c"))for _, _, record in query.results(): print(record["username"])# Output, in no guaranteed order:# Bob Roberts# rocketbobQuery by map key (no match)
Query for a key that does not exist in any record’s map. "z" appears only as a key of the nested "x" map, and a map-keys index without a context holds only top-level keys.
try (RecordStream rs = session.query(demo).where("$.foo.{@'z'}.exists()").execute()) { rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));}// Output: (none)for row in session.query(demo).where("$.foo.{@'z'}.exists()").execute(): print(row.record_or_raise().bins["username"])# Output: (none)let mut stmt = Statement::new("test", "demo", Bins::All);stmt.add_filter(Filter::contains("foo", "z", CollectionIndexType::MapKeys));let mut rs = client.query(&QueryPolicy::default(), PartitionFilter::all(), stmt) .await?.into_stream();while let Some(rec) = rs.next().await { println!("{}", rec?.bins["username"]);}// Output: (none)Statement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("demo");stmt.SetFilter(Filter.Contains("foo", IndexCollectionType.MAPKEYS, "z"));
RecordSet rs = client.Query(null, stmt);while (rs.Next()) { Console.WriteLine(rs.Record.GetString("username"));}rs.Close();// Output: (none)// Requires: import as "github.com/aerospike/aerospike-client-go/v8"stmt := as.NewStatement("test", "demo")stmt.SetFilter(as.NewContainsFilter("foo", as.ICT_MAPKEYS, "z"))rs, _ := client.Query(nil, stmt)for rec := range rs.Results() { fmt.Println(rec.Record.Bins["username"])}// Output: (none)const query = client.query('test', 'demo')query.where(filter.contains('foo', 'z', Aerospike.indexType.MAPKEYS))for (const rec of await query.results()) { console.log(rec.bins.username)}// Output: (none)as_query q;as_query_init(&q, "test", "demo");as_query_where_inita(&q, 1);as_query_where(&q, "foo", as_contains(MAPKEYS, STRING, "z"));aerospike_query_foreach(&as, &err, NULL, &q, query_cb, NULL);as_query_destroy(&q);// Output: (none)Statement stmt = new Statement();stmt.setNamespace("test");stmt.setSetName("demo");stmt.setFilter(Filter.contains("foo", IndexCollectionType.MAPKEYS, "z"));
RecordSet rs = client.query(null, stmt);while (rs.next()) { System.out.println(rs.getRecord().getString("username"));}rs.close();// Output: (none)query = client.query("test", "demo")query.where(p.contains("foo", aerospike.INDEX_TYPE_MAPKEYS, "z"))for _, _, record in query.results(): print(record["username"])# Output: (none)Known limitations
- When using range queries on maps, records can be returned multiple times if the map contains multiple values that fall within the range.