---
title: "Secondary index query"
description: "Learn how to perform secondary index queries on document records using the Aerospike C# client."
---

# Secondary index query

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

The following example demonstrates using a [secondary index](https://aerospike.com/docs/database/learn/architecture/data-storage/secondary-index) to find a document record. It does the following:

-   Create a document.
-   Add the document to an Aerospike set.
-   Create a secondary index.
-   Query the document using the secondary index.

The example demonstrates two ways of setting up a secondary index. The first approach stores the index target in a dedicated bin at write time. The second approach indexes values inside the document bin with a `MAPVALUES` index.

### Setup

Import the necessary helpers, create a client connection, and create a key.

```csharp
using Aerospike.Client;

using System;

using System.Collections.Generic;

AerospikeClient client = new("localhost", 3000);

string ns = "test";

string setName = "table1";
```

### Create a JSON document

Prepare the JSON document to be sent to Aerospike.

```csharp
List<Dictionary<string, object>> transactions = new()

{

    new() { ["txn_id"] = "1111", ["name"] = "Davis", ["item_id"] = "A1234", ["count"] = 1 },

    new() { ["txn_id"] = "2222", ["name"] = "Johnson", ["item_id"] = "B2345", ["count"] = 2 },

    new() { ["txn_id"] = "3333", ["name"] = "Johnson", ["item_id"] = "C3456", ["count"] = 2 },

    new() { ["txn_id"] = "4444", ["name"] = "Lee", ["item_id"] = "D4567", ["count"] = 3 }

};
```

### Write

Write the document to Aerospike.

```csharp
WritePolicy writePolicy = new()

{

    sendKey = true

};

foreach (Dictionary<string, object> transaction in transactions)

{

    Key key = new(ns, setName, transaction["txn_id"].ToString());

    Bin nameBin = new("name", transaction["name"]);

    Bin transactionBin = new("transaction", transaction);

    try

    {

        client.Put(writePolicy, key, nameBin, transactionBin);

        Record record = client.Get(null, key);

        Console.WriteLine("Create succeeded\nKey: {0}\nRecord: {1}",

            key.userKey, record);

    }

    catch (AerospikeException e)

    {

        Console.WriteLine("Create failed\nError: {0}", e.Message);

    }

}
```

### Create a secondary index on a dedicated bin

Create a secondary index on the dedicated `name` bin and execute a query. This approach stores the index target in its own bin during record insertion.

```csharp
try

{

    IndexTask task = client.CreateIndex(null, ns, setName, "test_name_idx", "name", IndexType.STRING);

    task.Wait();

    Console.WriteLine("Successfully created index test_name_idx on the 'name' bin");

}

catch (AerospikeException e)

{

    Console.WriteLine("Create index failed\nError: {0}", e.Message);

}

Statement stmt = new();

stmt.SetNamespace(ns);

stmt.SetSetName(setName);

stmt.SetBinNames("name", "transaction");

stmt.SetFilter(Filter.Equal("name", "Johnson"));

RecordSet rs = client.Query(null, stmt);

try

{

    while (rs.Next())

    {

        Console.WriteLine("Key: {0} | Record: {1}", rs.Key.userKey, rs.Record);

    }

}

finally

{

    rs.Close();

    client.DropIndex(null, ns, setName, "test_name_idx").Wait();

}
```

### Create a MAPVALUES index on the document bin

Create a secondary index on map values in the `transaction` bin and execute a query. This approach indexes nested values inside the document bin directly.

```csharp
try

{

    IndexTask task = client.CreateIndex(

        null, ns, setName, "test_transaction_idx", "transaction",

        IndexType.STRING, IndexCollectionType.MAPVALUES);

    task.Wait();

    Console.WriteLine("Successfully created index test_transaction_idx on the 'transaction' bin");

}

catch (AerospikeException e)

{

    Console.WriteLine("Create index failed\nError: {0}", e.Message);

}

Statement stmt = new();

stmt.SetNamespace(ns);

stmt.SetSetName(setName);

stmt.SetBinNames("name", "transaction");

stmt.SetFilter(Filter.Contains("transaction", IndexCollectionType.MAPVALUES, "Johnson"));

RecordSet rs = client.Query(null, stmt);

try

{

    while (rs.Next())

    {

        Console.WriteLine("Key: {0} | Record: {1}", rs.Key.userKey, rs.Record);

    }

}

finally

{

    rs.Close();

    client.DropIndex(null, ns, setName, "test_transaction_idx").Wait();

    client.Close();

}
```

## Code block — dedicated bin index

Expand this section for a single code block to run the dedicated bin index example.

```csharp
using Aerospike.Client;

using System;

using System.Collections.Generic;

AerospikeClient client = new("localhost", 3000);

string ns = "test";

string setName = "table1";

List<Dictionary<string, object>> transactions = new()

{

    new() { ["txn_id"] = "1111", ["name"] = "Davis", ["item_id"] = "A1234", ["count"] = 1 },

    new() { ["txn_id"] = "2222", ["name"] = "Johnson", ["item_id"] = "B2345", ["count"] = 2 },

    new() { ["txn_id"] = "3333", ["name"] = "Johnson", ["item_id"] = "C3456", ["count"] = 2 },

    new() { ["txn_id"] = "4444", ["name"] = "Lee", ["item_id"] = "D4567", ["count"] = 3 }

};

WritePolicy writePolicy = new()

{

    sendKey = true

};

foreach (Dictionary<string, object> transaction in transactions)

{

    Key key = new(ns, setName, transaction["txn_id"].ToString());

    Bin nameBin = new("name", transaction["name"]);

    Bin transactionBin = new("transaction", transaction);

    try

    {

        client.Put(writePolicy, key, nameBin, transactionBin);

        Record record = client.Get(null, key);

        Console.WriteLine("Create succeeded\nKey: {0}\nRecord: {1}", key.userKey, record);

    }

    catch (AerospikeException e)

    {

        Console.WriteLine("Create failed\nError: {0}", e.Message);

    }

}

try

{

    IndexTask task = client.CreateIndex(null, ns, setName, "test_name_idx", "name", IndexType.STRING);

    task.Wait();

    Console.WriteLine("Successfully created index test_name_idx on the 'name' bin");

}

catch (AerospikeException e)

{

    Console.WriteLine("Create index failed\nError: {0}", e.Message);

}

Statement stmt = new();

stmt.SetNamespace(ns);

stmt.SetSetName(setName);

stmt.SetBinNames("name", "transaction");

stmt.SetFilter(Filter.Equal("name", "Johnson"));

RecordSet rs = client.Query(null, stmt);

try

{

    while (rs.Next())

    {

        Console.WriteLine("Key: {0} | Record: {1}", rs.Key.userKey, rs.Record);

    }

}

finally

{

    rs.Close();

    client.DropIndex(null, ns, setName, "test_name_idx").Wait();

    client.Close();

}
```

## Code block — MAPVALUES index on document bin

Expand this section for a single code block to run the MAPVALUES index example.

```csharp
using Aerospike.Client;

using System;

using System.Collections.Generic;

AerospikeClient client = new("localhost", 3000);

string ns = "test";

string setName = "table1";

List<Dictionary<string, object>> transactions = new()

{

    new() { ["txn_id"] = "1111", ["name"] = "Davis", ["item_id"] = "A1234", ["count"] = 1 },

    new() { ["txn_id"] = "2222", ["name"] = "Johnson", ["item_id"] = "B2345", ["count"] = 2 },

    new() { ["txn_id"] = "3333", ["name"] = "Johnson", ["item_id"] = "C3456", ["count"] = 2 },

    new() { ["txn_id"] = "4444", ["name"] = "Lee", ["item_id"] = "D4567", ["count"] = 3 }

};

WritePolicy writePolicy = new()

{

    sendKey = true

};

foreach (Dictionary<string, object> transaction in transactions)

{

    Key key = new(ns, setName, transaction["txn_id"].ToString());

    Bin nameBin = new("name", transaction["name"]);

    Bin transactionBin = new("transaction", transaction);

    try

    {

        client.Put(writePolicy, key, nameBin, transactionBin);

        Record record = client.Get(null, key);

        Console.WriteLine("Create succeeded\nKey: {0}\nRecord: {1}", key.userKey, record);

    }

    catch (AerospikeException e)

    {

        Console.WriteLine("Create failed\nError: {0}", e.Message);

    }

}

try

{

    IndexTask task = client.CreateIndex(

        null, ns, setName, "test_transaction_idx", "transaction",

        IndexType.STRING, IndexCollectionType.MAPVALUES);

    task.Wait();

    Console.WriteLine("Successfully created index test_transaction_idx on the 'transaction' bin");

}

catch (AerospikeException e)

{

    Console.WriteLine("Create index failed\nError: {0}", e.Message);

}

Statement stmt = new();

stmt.SetNamespace(ns);

stmt.SetSetName(setName);

stmt.SetBinNames("name", "transaction");

stmt.SetFilter(Filter.Contains("transaction", IndexCollectionType.MAPVALUES, "Johnson"));

RecordSet rs = client.Query(null, stmt);

try

{

    while (rs.Next())

    {

        Console.WriteLine("Key: {0} | Record: {1}", rs.Key.userKey, rs.Record);

    }

}

finally

{

    rs.Close();

    client.DropIndex(null, ns, setName, "test_transaction_idx").Wait();

    client.Close();

}
```