---
title: "Map indexes and querying"
description: "Learn how to create secondary indexes on Aerospike map keys and values and perform equality or range queries."
---

# Map indexes and querying

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

## Overview

This page describes how to create a [secondary index](https://aerospike.com/docs/database/learn/architecture/data-storage/secondary-index#secondary-index-creation) 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](https://aerospike.com/docs/develop/data-types/collections/#nesting-depth-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`](https://aerospike.com/docs/database/tools/asadm). For index management options, see [Secondary index queries](https://aerospike.com/docs/develop/learn/queries/secondary-index/#create-an-index).

Create an index with source type `mapkeys` and a String data type:

Terminal window

```bash
Admin+> manage sindex create string foo_mapkey_idx in mapkeys ns test set demo bin foo
```

Create an index with source type `mapvalues` and an integer data type:

Terminal window

```bash
Admin+> manage sindex create integer foo_mapval_idx in mapvalues ns test set demo bin foo
```

::: note
Prior to Database 8.2.0, use `numeric` in place of `integer`.
:::

Use `show sindex` to confirm the indexes were created successfully. Current versions of `asadm` display `integer` in the Bin Type column; older versions display `numeric`.

Terminal window

```bash
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  |RW

foo_mapval_idx|test     |demo|foo|integer|mapvalues|RW

Number of rows: 2
```

Elements 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

-   [Java SDK](#tab-panel-5447)
-   [Python SDK](#tab-panel-5448)
-   [Rust](#tab-panel-5449)
-   [C#](#tab-panel-5450)
-   [Go](#tab-panel-5451)
-   [Node.js](#tab-panel-5452)
-   [C](#tab-panel-5453)
-   [Java](#tab-panel-5454)
-   [Python](#tab-panel-5455)

```java
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();
```

```python
from aerospike_sdk import Behavior, DataSet

from 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()
```

```rust
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?;
```

```csharp
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));
```

```go
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",

    }),

)
```

```javascript
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' },

})
```

```c
#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);
```

```java
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));
```

```python
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.

-   [Java SDK](#tab-panel-5456)
-   [Python SDK](#tab-panel-5457)
-   [Rust](#tab-panel-5458)
-   [C#](#tab-panel-5459)
-   [Go](#tab-panel-5460)
-   [Node.js](#tab-panel-5461)
-   [C](#tab-panel-5462)
-   [Java](#tab-panel-5463)
-   [Python](#tab-panel-5464)

```java
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 Roberts
```

```python
for row in session.query(demo).where("$.foo.{=1}.exists()").execute():

    print(row.record_or_raise().bins["username"])

# Output: Bob Roberts
```

```rust
use 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 Roberts
```

```csharp
Statement 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 Roberts
```

```go
import (

    "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 Roberts
```

```javascript
const 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
```

```c
#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 Roberts
```

```java
import 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 Roberts
```

```python
from 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 Roberts
```

### Query 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.

-   [Java SDK](#tab-panel-5465)
-   [Python SDK](#tab-panel-5466)
-   [Rust](#tab-panel-5467)
-   [C#](#tab-panel-5468)
-   [Go](#tab-panel-5469)
-   [Node.js](#tab-panel-5470)
-   [C](#tab-panel-5471)
-   [Java](#tab-panel-5472)
-   [Python](#tab-panel-5473)

```java
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

// rocketbob
```

```python
for row in session.query(demo).where("$.foo.{=3}.exists()").execute():

    print(row.record_or_raise().bins["username"])

# Output, in no guaranteed order:

# Bob Roberts

# rocketbob
```

```rust
let 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

// rocketbob
```

```csharp
Statement 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
```

```go
// 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

// rocketbob
```

```javascript
const 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

// rocketbob
```

```c
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)3));

aerospike_query_foreach(&as, &err, NULL, &q, query_cb, NULL);

as_query_destroy(&q);

// Output, in no guaranteed order:

// Bob Roberts

// rocketbob
```

```java
Statement 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

// rocketbob
```

```python
query = 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

# rocketbob
```

### Query 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](#known-limitations)).

-   [Java SDK](#tab-panel-5474)
-   [Python SDK](#tab-panel-5475)
-   [Rust](#tab-panel-5476)
-   [C#](#tab-panel-5477)
-   [Go](#tab-panel-5478)
-   [Node.js](#tab-panel-5479)
-   [C](#tab-panel-5480)
-   [Java](#tab-panel-5481)
-   [Python](#tab-panel-5482)

```java
// 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
```

```python
# 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

# rocketbob
```

```rust
let 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

// rocketbob
```

```csharp
Statement 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
```

```go
// 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

// rocketbob
```

```javascript
const 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

// rocketbob
```

```c
as_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

// rocketbob
```

```java
Statement 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

// rocketbob
```

```python
query = 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

# rocketbob
```

### Query by map key (string equality)

Query `foo_mapkey_idx` for records where the `foo` map contains the key `"y"`.

-   [Java SDK](#tab-panel-5483)
-   [Python SDK](#tab-panel-5484)
-   [Rust](#tab-panel-5485)
-   [C#](#tab-panel-5486)
-   [Go](#tab-panel-5487)
-   [Node.js](#tab-panel-5488)
-   [C](#tab-panel-5489)
-   [Java](#tab-panel-5490)
-   [Python](#tab-panel-5491)

```java
try (RecordStream rs = session.query(demo).where("$.foo.{@'y'}.exists()").execute()) {

    rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));

}

// Output: samunwise
```

```python
for row in session.query(demo).where("$.foo.{@'y'}.exists()").execute():

    print(row.record_or_raise().bins["username"])

# Output: samunwise
```

```rust
let 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: samunwise
```

```csharp
Statement 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
```

```go
// 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: samunwise
```

```javascript
const 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: samunwise
```

```c
as_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: samunwise
```

```java
Statement 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: samunwise
```

```python
query = client.query("test", "demo")

query.where(p.contains("foo", aerospike.INDEX_TYPE_MAPKEYS, "y"))

for _, _, record in query.results():

    print(record["username"])

# Output: samunwise
```

### Query by map key (multiple matches)

Query for records where the `foo` map contains the key `"c"`. Both `u1` and `u2` have a `"c"` key.

-   [Java SDK](#tab-panel-5492)
-   [Python SDK](#tab-panel-5493)
-   [Rust](#tab-panel-5494)
-   [C#](#tab-panel-5495)
-   [Go](#tab-panel-5496)
-   [Node.js](#tab-panel-5497)
-   [C](#tab-panel-5498)
-   [Java](#tab-panel-5499)
-   [Python](#tab-panel-5500)

```java
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

// rocketbob
```

```python
for row in session.query(demo).where("$.foo.{@'c'}.exists()").execute():

    print(row.record_or_raise().bins["username"])

# Output, in no guaranteed order:

# Bob Roberts

# rocketbob
```

```rust
let 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

// rocketbob
```

```csharp
Statement 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
```

```go
// 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

// rocketbob
```

```javascript
const 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

// rocketbob
```

```c
as_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

// rocketbob
```

```java
Statement 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

// rocketbob
```

```python
query = 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

# rocketbob
```

### Query 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.

-   [Java SDK](#tab-panel-5501)
-   [Python SDK](#tab-panel-5502)
-   [Rust](#tab-panel-5503)
-   [C#](#tab-panel-5504)
-   [Go](#tab-panel-5505)
-   [Node.js](#tab-panel-5506)
-   [C](#tab-panel-5507)
-   [Java](#tab-panel-5508)
-   [Python](#tab-panel-5509)

```java
try (RecordStream rs = session.query(demo).where("$.foo.{@'z'}.exists()").execute()) {

    rs.forEachRemaining(r -> System.out.println(r.recordOrThrow().getString("username")));

}

// Output: (none)
```

```python
for row in session.query(demo).where("$.foo.{@'z'}.exists()").execute():

    print(row.record_or_raise().bins["username"])

# Output: (none)
```

```rust
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)
```

```csharp
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)
```

```go
// 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)
```

```javascript
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)
```

```c
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)
```

```java
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)
```

```python
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.