---
title: "Tutorial for Expression Indexes"
description: "Tutorial for creating and querying sparse expression indexes in Aerospike Database 8.1.0+."
---

# Tutorial for Expression Indexes

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

This tutorial introduces expression indexes in Aerospike Database. This tutorial assumes you are familiar with [secondary indexes](https://aerospike.com/docs/database/learn/architecture/data-storage/secondary-index/) and [expressions](https://aerospike.com/docs/develop/expressions/) in Aerospike Database.

## Overview

Expression indexes build sparse secondary indexes over computed values defined by an Aerospike expression. Instead of indexing every record or persisting derived bins, the index evaluates your expression and includes only the records that match.

In this tutorial, you will:

-   Create your first expression index
-   Run your first [query](https://aerospike.com/docs/develop/learn/queries/secondary-index/) against it
-   Compare expression indexes against traditional secondary indexes

::: note
Prior to Database 8.1.0, secondary indexes were limited to raw data, or fields other than the primary key.
:::

### Why it matters

-   **Simpler application code:** push filter logic into the index; no extra bins or duplicated client filters.
-   **Reduced memory footprint:** indexes include only relevant records.
-   **Total cost of ownership:** reduced RAM and compute requirements lower infrastructure spend.
-   **Faster queries:** less to scan means lower latency.

### When to use expression indexes

Use them when you would otherwise:

-   Persist a derived value solely to make it indexable.
-   Index every record even though only a subset are needed for business logic.
-   Re-implement the same filter logic across multiple clients or languages.

## Get started

### Prerequisites

-   A running instance of Aerospike Database 8.1.0 or later
-   Updated Client (minimum versions):
    -   [Java: v9.1.0+](https://aerospike.com/docs/develop/client/java/install/)
    -   [Python: v17.1.0+](https://aerospike.com/docs/develop/client/python/install/)
    -   [C: v7.1.0+](https://aerospike.com/docs/develop/client/c/install/)
    -   [C#: v8.1.0+](https://aerospike.com/docs/develop/client/csharp/install/)
    -   [Go: v8.4.0+](https://aerospike.com/docs/develop/client/go/install/)
    -   [Node.js: v6.3.0+](https://aerospike.com/docs/develop/client/node/install/)
    -   Rust: not available
    -   PHP: not available

Verify your server version using [asinfo](https://aerospike.com/docs/database/tools/asinfo/):

Terminal window

```bash
# Verify you’re running Aerospike 8.1.0+

    asinfo -v build
```

### Create expression, index, and query

1.  Create the expression.
    
    The following example creates the “adult users in target countries” expression. For this example, let’s assume an adult is someone 18 or older, and our target countries are Australia, Canada and Botswana.
    
    For this tutorial, we’ll generate the Base64 representation of the expression in the client and then use the `asadm` command-line tool to create the index. This approach separates application logic (defining the filter) from database administration (creating the index).
    
    -   [Java](#tab-panel-2472)
    -   [Python](#tab-panel-2473)
    -   [C](#tab-panel-2474)
    -   [Go](#tab-panel-2475)
    -   [C#](#tab-panel-2476)
    -   [Node.js](#tab-panel-2477)
    
    ```java
    // Build an expression that indexes age only for adults in AU/CA/BW that are 18 or older
    
    Expression filterExp = Exp.build(
    
            Exp.cond(
    
                Exp.and(
    
                    Exp.ge(// Is the age 18 or older?
    
                            Exp.intBin("age"),
    
                            Exp.val(18)
    
                    ),
    
                    Exp.or( // Do they live in a target country?
    
                            Exp.eq(Exp.stringBin("country"), Exp.val("Australia")),
    
                            Exp.eq(Exp.stringBin("country"), Exp.val("Canada")),
    
                            Exp.eq(Exp.stringBin("country"), Exp.val("Botswana"))
    
                    )
    
                ),
    
                Exp.intBin("age"), // If true, return the age of the customer to be indexed
    
                Exp.unknown() // returns "unknown" to exclude the record from the index
    
            )
    
        );
    
    System.out.println(filterExp.getBase64());
    
    // Prints: lHuTEJMEk1ECo2FnZRKUEZMBk1EDp2NvdW50cnmqA0F1c3RyYWxpYZMBk1EDp2NvdW50cnmnA0NhbmFkYZMBk1EDp2NvdW50cnmpA0JvdHN3YW5hk1ECo2FnZZEA
    ```
    
    ```python
    # pip install aerospike
    
    import aerospike
    
    from aerospike_helpers import expressions as exp
    
    target_countries = ["Australia", "Canada", "Botswana"]
    
    # Build the "OR" condition for the country check
    
    country_is_target = exp.Or(
    
        *[exp.Eq(exp.StrBin("country"), c) for c in target_countries]
    
    )
    
    # Compile the final expression
    
    filter_exp = exp.Cond(
    
        # IF block: Both conditions must be true
    
        exp.And(
    
            exp.GE(exp.IntBin("age"), 18),
    
            country_is_target
    
        ),
    
        # Return the value of the 'age' bin for indexing
    
        exp.IntBin("age"),
    
        # ELSE Return "unknown" to exclude the record from the index
    
        exp.Unknown()
    
    ).compile()
    
    # Get Base64 for use with asadm `exp_base64`
    
    client = aerospike.client({"hosts": [("127.0.0.1", 3000)]}).connect()
    
    expr_b64 = client.get_expression_base64(filter_exp)
    
    print(expr_b64)
    
    # prints: lHuTEJMEk1ECo2FnZRKUEZMBk1EDp2NvdW50cnmqA0F1c3RyYWxpYZMBk1EDp2NvdW50cnmnA0NhbmFkYZMBk1EDp2NvdW50cnmpA0JvdHN3YW5hk1ECo2FnZZEA
    
    client.close()
    ```
    
    ```c
    as_exp_build(filter_exp,
    
      as_exp_cond(
    
        as_exp_and(
    
          as_exp_cmp_ge(
    
            as_exp_bin_int("age"),
    
            as_exp_int(18)),
    
          as_exp_or(
    
            as_exp_cmp_eq(as_exp_bin_str("country"), as_exp_str("Australia")),
    
            as_exp_cmp_eq(as_exp_bin_str("country"), as_exp_str("Canada")),
    
            as_exp_cmp_eq(as_exp_bin_str("country"), as_exp_str("Botswana"))
    
            )),
    
        // If true, return the value in the age bin
    
        as_exp_bin_int("age"),
    
        // return unknown to exclude value from index
    
        as_exp_unknown()
    
      ));
    
    LOG("Expression base64 = %s", as_exp_to_base64(filter_exp));
    
    // Prints:
    
    // Expression base64 = lHuTEJMEk1ECo2FnZRKUEZMBk1EDp2NvdW50cnmqA0F1c3RyYWxpYZMBk1EDp2NvdW50cnmnA0NhbmFkYZMBk1EDp2NvdW50cnmpA0JvdHN3YW5hk1ECo2FnZZEA
    ```
    
    ```go
    // go get github.com/aerospike/aerospike-client-go/v8
    
    import (
    
        "fmt"
    
        as "github.com/aerospike/aerospike-client-go/v8"
    
    )
    
    // Build an expression that indexes age only for adults in AU/CA/BW that are 18 or older
    
    filterExp := as.ExpCond(
    
        as.ExpAnd(
    
            // Is the age 18 or older?
    
            as.ExpGreaterEq(as.ExpIntBin("age"), as.ExpIntVal(18)),
    
            // Do they live in a target country?
    
            as.ExpOr(
    
                as.ExpEq(as.ExpStringBin("country"), as.ExpStringVal("Australia")),
    
                as.ExpEq(as.ExpStringBin("country"), as.ExpStringVal("Canada")),
    
                as.ExpEq(as.ExpStringBin("country"), as.ExpStringVal("Botswana")),
    
            ),
    
        ),
    
        // If true, return the age of the customer to be indexed
    
        as.ExpIntBin("age"),
    
        // Otherwise return "unknown" to exclude the record from the index
    
        as.ExpUnknown(),
    
    )
    
    b64, err := filterExp.Base64()
    
    if err != nil {
    
        panic(err)
    
    }
    
    fmt.Println(b64)
    
    // Prints: lHuTEJMEk1ECo2FnZRKUEZMBk1EDp2NvdW50cnmqA0F1c3RyYWxpYZMBk1EDp2NvdW50cnmnA0NhbmFkYZMBk1EDp2NvdW50cnmpA0JvdHN3YW5hk1ECo2FnZZEA
    ```
    
    ```c#
    // Build an expression that indexes age only for adults in AU/CA/BW
    
    Expression filterExp = Exp.Build(
    
        // The `Cond` expression is the top-level IF/THEN/ELSE
    
        Exp.Cond(
    
            // IF block: Defines the conditions for the index
    
            Exp.And(
    
                // Condition 1: Is the age 18 or older?
    
                Exp.GE(Exp.IntBin("age"), Exp.Val(18)),
    
                // Condition 2: Do they live in a target country?
    
                Exp.Or(
    
                    Exp.Eq(Exp.StringBin("country"), Exp.Val("Australia")),
    
                    Exp.Eq(Exp.StringBin("country"), Exp.Val("Canada")),
    
                    Exp.Eq(Exp.StringBin("country"), Exp.Val("Botswana"))
    
                )
    
            ),
    
            // If true, return the integer value from the 'age' bin.
    
            // This value is what gets indexed.
    
            Exp.IntBin("age"),
    
            // ELSE If false, return "unknown".
    
            // This excludes the record from the index.
    
            Exp.Unknown()
    
        )
    
    );
    
    // Print the Base64-encoded expression for use with asadm
    
    string exprBase64 = filterExp.GetBase64();
    
    Console.WriteLine("Expression Base64:");
    
    Console.WriteLine(exprBase64);
    
    // Prints: lHuTEJMEk1ECo2FnZRKUEZMBk1EDp2NvdW50cnmqA0F1c3RyYWxpYZMBk1EDp2NvdW50cnmnA0NhbmFkYZMBk1EDp2NvdW50cnmpA0JvdHN3YW5hk1ECo2FnZZEA
    ```
    
    ```js
    // npm install aerospike
    
    import Aerospike from "aerospike";
    
    const exp = Aerospike.exp;
    
    const filterExp = exp.cond(
    
      exp.and(
    
        exp.ge(exp.binInt("age"), exp.int(18)),
    
        exp.or(
    
          exp.eq(exp.binStr("country"), exp.str("Australia")),
    
          exp.eq(exp.binStr("country"), exp.str("Canada")),
    
          exp.eq(exp.binStr("country"), exp.str("Botswana")),
    
        ),
    
      ),
    
      exp.binInt("age"),
    
      exp.unknown(),
    
    );
    
    // Get Base64 for use with asadm `exp_base64` (requires a connected client)
    
    const client = await Aerospike.connect({ hosts: "127.0.0.1:3000" });
    
    console.log(client.expressionToBase64(filterExp));
    
    // Prints: lHuTEJMEk1ECo2FnZRKUEZMBk1EDp2NvdW50cnmqA0F1c3RyYWxpYZMBk1EDp2NvdW50cnmnA0NhbmFkYZMBk1EDp2NvdW50cnmpA0JvdHN3YW5hk1ECo2FnZZEA
    
    await client.close();
    ```
    
    All the client examples above print similar Base64-encoded expression strings to the console.
    
2.  Create the expression index.
    
    Use the `asadm` command-line tool to create a numeric secondary index on the expression. Copy the full Base64 string from the previous step’s output and use it in the command below.
    
    Terminal window
    
    ```bash
    asadm -e "enable; manage sindex create numeric cust_index ns test set cust_data exp_base64 lHuTEJMEk1ECo2FnZRKUEZMBk1EDp2NvdW50cnmqA0F1c3RyYWxpYZMBk1EDp2NvdW50cnmnA0NhbmFkYZMBk1EDp2NvdW50cnmpA0JvdHN3YW5hk1ECo2FnZZEA"
    ```
    
3.  Insert some test data.
    
    -   [Java](#tab-panel-2478)
    -   [Python](#tab-panel-2479)
    -   [C](#tab-panel-2480)
    -   [Go](#tab-panel-2481)
    -   [C#](#tab-panel-2482)
    -   [Node.js](#tab-panel-2483)
    
    ```java
    // Define the namespace and set for the records
    
    final String NAMESPACE = "test";
    
    final String SET = "cust_data";
    
    // A helper method to insert a customer record
    
    public void insert(int key, String name, int age, String country) {
    
        client.put(null,
    
                new Key(NAMESPACE, SET, key),
    
                new Bin("name", name),
    
                new Bin("age", age),
    
                new Bin("country", country));
    
    }
    
    // Insert sample customers to demonstrate which records get indexed
    
    public void insertData() {
    
        insert(1, "Tim", 312, "Australia");
    
        insert(2, "Bob", 47, "Canada");
    
        insert(3, "Jo", 15, "USA"); // not indexed
    
        insert(4, "Steven", 23, "Botswana");
    
        insert(5, "Susan", 32, "Canada");
    
        insert(6, "Jess", 17, "Botswana"); // not indexed
    
        insert(7, "Sam", 18, "USA"); // not indexed
    
        insert(8, "Alex", 47, "Canada");
    
        insert(9, "Pam", 56, "Australia");
    
        insert(10, "Vivek", 12, "India"); // not indexed
    
        insert(11, "Kiril", 22, "Sweden"); // not indexed
    
        insert(12, "Bill", 23, "UK"); // not indexed
    
    }
    ```
    
    ```python
    import aerospike
    
    # Sample customer data
    
    customers = [
    
        (1, "Tim", 312, "Australia"),
    
        (2, "Bob", 47, "Canada"),
    
        (3, "Jo", 15, "USA"),           # not indexed
    
        (4, "Steven", 23, "Botswana"),
    
        (5, "Susan", 32, "Canada"),
    
        (6, "Jess", 17, "Botswana"),    # not indexed
    
        (7, "Sam", 18, "USA"),          # not indexed
    
        (8, "Alex", 47, "Canada"),
    
        (9, "Pam", 56, "Australia"),
    
        (10, "Vivek", 12, "India"),     # not indexed
    
        (11, "Kiril", 22, "Sweden"),    # not indexed
    
        (12, "Bill", 23, "UK")          # not indexed
    
    ]
    
    # Client configuration (replace with your actual configuration)
    
    config = {"hosts": [("127.0.0.1", 3000)]}
    
    client = aerospike.client(config).connect()
    
    # Inserts data
    
    for key, name, age, country in customers:
    
        client.put(
    
            ("test", "cust_data", key),
    
            {
    
                "name": name,
    
                "age": age,
    
                "country": country
    
            }
    
        )
    
    client.close()
    ```
    
    ```c
    static void
    
    do_insert_data(aerospike* as)
    
    {
    
      insert(as, 1, "Tim", 312, "Australia");
    
      insert(as, 2, "Bob", 47, "Canada");
    
      insert(as, 3, "Jo", 15, "USA"); // not indexed
    
      insert(as, 4, "Steven", 23, "Botswana");
    
      insert(as, 5, "Susan", 32, "Canada");
    
      insert(as, 6, "Jess", 17, "Botswana"); // not indexed
    
      insert(as, 7, "Sam", 18, "USA"); // not indexed
    
      insert(as, 8, "Alex", 47, "Canada");
    
      insert(as, 9, "Pam", 56, "Australia");
    
      insert(as, 10, "Vivek", 12, "India"); // not indexed
    
      insert(as, 11, "Kiril", 22, "Sweden"); // not indexed
    
      insert(as, 12, "Bill", 23, "UK"); // not indexed
    
    }
    
    extern char* g_namespace;
    
    extern char* g_set;
    
    static void
    
    insert(aerospike* as, int key, const char* name, int age, const char* country)
    
    {
    
      as_error err;
    
      as_error_init(&err);
    
      as_key int_key;
    
      as_key_init_int64(&int_key, g_namespace, g_set, key);
    
      as_record rec;
    
      as_record_inita(&rec, 3);
    
      as_record_set_str(&rec, "name", name);
    
      as_record_set_int64(&rec, "age", age);
    
      as_record_set_str(&rec, "country", country);
    
      if (aerospike_key_put(as, &err, NULL, &int_key, &rec) != AEROSPIKE_OK) {
    
        LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
    
        example_cleanup(as);
    
        exit(-1);
    
      }
    
      as_record_destroy(&rec);
    
    }
    ```
    
    ```go
    import (
    
        "fmt"
    
        as "github.com/aerospike/aerospike-client-go/v8"
    
    )
    
    // Define the namespace and set for the records
    
    const (
    
        NAMESPACE = "test"
    
        SET       = "cust_data"
    
    )
    
    // A helper to insert a customer record
    
    func insert(client *as.Client, id int, name string, age int, country string) {
    
        key, _ := as.NewKey(NAMESPACE, SET, id)
    
        if err := client.PutBins(nil, key,
    
            as.NewBin("name", name),
    
            as.NewBin("age", age),
    
            as.NewBin("country", country)); err != nil {
    
            panic(err)
    
        }
    
    }
    
    func doInsertData(client *as.Client) {
    
        insert(client, 1, "Tim", 312, "Australia")
    
        insert(client, 2, "Bob", 47, "Canada")
    
        insert(client, 3, "Jo", 15, "USA")           // not indexed
    
        insert(client, 4, "Steven", 23, "Botswana")
    
        insert(client, 5, "Susan", 32, "Canada")
    
        insert(client, 6, "Jess", 17, "Botswana")    // not indexed
    
        insert(client, 7, "Sam", 18, "USA")          // not indexed
    
        insert(client, 8, "Alex", 47, "Canada")
    
        insert(client, 9, "Pam", 56, "Australia")
    
        insert(client, 10, "Vivek", 12, "India")     // not indexed
    
        insert(client, 11, "Kiril", 22, "Sweden")    // not indexed
    
        insert(client, 12, "Bill", 23, "UK")         // not indexed
    
    }
    
    // Connect and load the data
    
    client, err := as.NewClient("127.0.0.1", 3000)
    
    if err != nil {
    
        panic(err)
    
    }
    
    defer client.Close()
    
    doInsertData(client)
    
    fmt.Println("Insert data: done")
    ```
    
    ```c#
    // Define the namespace and set for the records
    
    const string NAMESPACE = "test";
    
    const string SET = "cust_data";
    
    // A helper method to insert a customer record
    
    public void Insert(int key, string name, int age, string country)
    
    {
    
        client.Put(null,
    
            new Key(NAMESPACE, SET, key),
    
            new Bin("name", name),
    
            new Bin("age", age),
    
            new Bin("country", country));
    
    }
    
    // Insert sample customers to demonstrate which records get indexed
    
    public void InsertData()
    
    {
    
        Insert(1, "Tim", 312, "Australia");
    
        Insert(2, "Bob", 47, "Canada");
    
        Insert(3, "Jo", 15, "USA"); // not indexed
    
        Insert(4, "Steven", 23, "Botswana");
    
        Insert(5, "Susan", 32, "Canada");
    
        Insert(6, "Jess", 17, "Botswana"); // not indexed
    
        Insert(7, "Sam", 18, "USA"); // not indexed
    
        Insert(8, "Alex", 47, "Canada");
    
        Insert(9, "Pam", 56, "Australia");
    
        Insert(10, "Vivek", 12, "India"); // not indexed
    
        Insert(11, "Kiril", 22, "Sweden"); // not indexed
    
        Insert(12, "Bill", 23, "UK"); // not indexed
    
    }
    ```
    
    ```js
    import Aerospike from "aerospike";
    
    const key = Aerospike.Key;
    
    // Define the namespace and set for the records
    
    const NAMESPACE = "test";
    
    const SET = "cust_data";
    
    const client = await Aerospike.connect({
    
      hosts: "127.0.0.1:3000",
    
    });
    
    // Sample customer data
    
    const customers = [
    
      { key: 1, name: "Tim", age: 312, country: "Australia" },
    
      { key: 2, name: "Bob", age: 47, country: "Canada" },
    
      { key: 3, name: "Jo", age: 15, country: "USA" },
    
      { key: 4, name: "Steven", age: 23, country: "Botswana" },
    
      { key: 5, name: "Susan", age: 32, country: "Canada" },
    
      { key: 6, name: "Jess", age: 17, country: "Botswana" },
    
      { key: 7, name: "Sam", age: 18, country: "USA" },
    
      { key: 8, name: "Alex", age: 47, country: "Canada" },
    
      { key: 9, name: "Pam", age: 56, country: "Australia" },
    
      { key: 10, name: "Vivek", age: 12, country: "India" },
    
      { key: 11, name: "Kiril", age: 22, country: "Sweden" },
    
      { key: 12, name: "Bill", age: 23, country: "UK" },
    
    ];
    
    // Insert sample customers to demonstrate which records get indexed
    
    const promises = customers.map((customer) => {
    
      return client.put(new key(NAMESPACE, SET, customer.key), {
    
        name: customer.name,
    
        age: customer.age,
    
        country: customer.country,
    
      });
    
    });
    
    await Promise.all(promises);
    
    await client.close();
    ```
    
4.  Validate index entries.
    
    You should see 6 entries in the expression index (records 1, 2, 4, 5, 8, 9).
    
    Terminal window
    
    ```bash
    # Confirm only matching records (6) were indexed
    
    asinfo -v 'sindex-stat:namespace=test;indexname=cust_index' -l
    
    entries=6
    
    ...
    ```
    
5.  Query your Expression Index.
    
    Run a query to filter for ages 5 and above. Notice the results still only shows ages 18 and above.
    
    -   [Java](#tab-panel-2484)
    -   [Python](#tab-panel-2485)
    -   [C](#tab-panel-2486)
    -   [Go](#tab-panel-2487)
    -   [C#](#tab-panel-2488)
    -   [Node.js](#tab-panel-2489)
    
    ```java
    // Query via the expression index to fetch records for customers that are 5 and older
    
    Statement stmt = new Statement();
    
    stmt.setNamespace("test");
    
    stmt.setSetName("cust_data");
    
    // Use `rangeByIndex` to query the expression index
    
    stmt.setFilter(Filter.rangeByIndex("cust_index", 5, Integer.MAX_VALUE));
    
    // Execute the query and print the results
    
    try (RecordSet recordSet = client.query(null, stmt)) {
    
        while (recordSet.next()) {
    
            System.out.println(recordSet.getRecord());
    
        }
    
    }
    ```
    
    ```python
    import sys
    
    import aerospike
    
    from aerospike import predicates as p
    
    # Connect to the database
    
    config = {"hosts": [("127.0.0.1", 3000)]}
    
    client = aerospike.client(config).connect()
    
    # Create a query object
    
    q = client.query("test", "cust_data")
    
    # Set the query to use the expression index with a range filter
    
    q.where_with_index_name("cust_index",
    
                p.range(None, aerospike.INDEX_TYPE_DEFAULT, 5, sys.maxsize))
    
    # Define a function to handle each record returned by the query
    
    def handle(record):
    
        key, meta, bins = record
    
        print(bins)
    
    # Execute the query and apply the handler to each record
    
    q.foreach(handle)
    
    client.close()
    ```
    
    ```c
    static bool query_cb(const as_val*, void*);
    
    static bool print_bin_cb(const char*, const as_val*, void*);
    
    static void
    
    do_query_by_age_at_least_5(aerospike* as)
    
    {
    
      as_query query;
    
      as_query_init(&query, g_namespace, g_set);
    
      as_query_where_init(&query, 1);
    
      as_query_where_with_index_name(&query, "cust_index",
    
                       as_integer_range(5, INT_MAX));
    
      as_error err;
    
      if (aerospike_query_foreach(as, &err, NULL, &query, &query_cb, NULL) !=
    
          AEROSPIKE_OK) {
    
        LOG("aerospike_query_foreach() returned %d - %s", err.code, err.message);
    
        example_cleanup(as);
    
        exit(-1);
    
      }
    
      example_cleanup(&as);
    
      return 0;
    
    }
    
    static bool
    
    query_cb(const as_val* val, void* udata) {
    
      if (! val) {
    
        // Query is complete.
    
        return false;
    
      }
    
      as_record* rec = as_record_fromval(val);
    
      as_record_foreach(rec, print_bin_cb, NULL);
    
      printf("\n");
    
      return true;
    
    }
    
    static bool
    
    print_bin_cb(const char* name, const as_val* val, void* udata) {
    
      printf("%s=", name);
    
      uint64_t bin_type = as_val_type(val);
    
      switch (bin_type) {
    
      case AS_STRING:
    
        printf("\"%s\", ", as_string_get(as_string_fromval(val)));
    
        return true;
    
      case AS_INTEGER:
    
        printf("%lld, ", as_integer_get(as_integer_fromval(val)));
    
        return true;
    
      default:
    
        LOG("print_bin_cb: unknown type %llu for bin named %s", bin_type, name);
    
        return false;
    
      }
    
    }
    ```
    
    ```go
    import (
    
        "fmt"
    
        "math"
    
        as "github.com/aerospike/aerospike-client-go/v8"
    
    )
    
    // Query via the expression index to fetch records for customers that are 5 and older
    
    stmt := as.NewStatement("test", "cust_data")
    
    // Use `NewRangeWithIndexNameFilter` to query the expression index
    
    stmt.SetFilter(as.NewRangeWithIndexNameFilter("cust_index", 5, math.MaxInt64))
    
    rs, err := client.Query(nil, stmt)
    
    if err != nil {
    
        panic(err)
    
    }
    
    for rec := range rs.Results() {
    
        if rec.Err != nil {
    
            fmt.Printf("error: %v\n", rec.Err)
    
            continue
    
        }
    
        fmt.Println(rec.Record.Bins)
    
    }
    ```
    
    ```c#
    // Query via the expression index to fetch records for customers that are 5 and older
    
    Statement stmt = new();
    
    stmt.SetNamespace("test");
    
    stmt.SetSetName("cust_data");
    
    // Use `RangeByIndex` to query the expression index
    
    stmt.SetFilter(Filter.RangeByIndex("cust_index", 5, int.MaxValue));
    
    // Execute the query and print the results
    
    try
    
    {
    
        using RecordSet recordSet = client.Query(null, stmt);
    
        while (recordSet.Next())
    
        {
    
            Console.WriteLine(recordSet.Record);
    
        }
    
    }
    ```
    
    ```js
    import Aerospike from "aerospike";
    
    const filter = Aerospike.filter;
    
    // Define the namespace and set for the records
    
    const NAMESPACE = "test";
    
    const SET = "cust_data";
    
    const client = await Aerospike.connect({
    
      hosts: "127.0.0.1:3000",
    
    });
    
    // Create a query object
    
    const query = client.query(NAMESPACE, SET);
    
    // Query via the expression index to fetch records for customers that are 5 and older
    
    query.whereWithIndexName(
    
      filter.range(null, 5, Number.MAX_SAFE_INTEGER),
    
      "cust_index",
    
    );
    
    // Execute the query and print the results
    
    const results = await query.results();
    
    for (const result of results) {
    
      console.log(result);
    
    }
    
    await client.close();
    ```
    
    Since we stored age, you can filter for records above 25 by simply modifying the query:
    
    -   [Java](#tab-panel-2490)
    -   [Python](#tab-panel-2491)
    -   [C](#tab-panel-2492)
    -   [Go](#tab-panel-2493)
    -   [C#](#tab-panel-2494)
    -   [Node.js](#tab-panel-2495)
    
    ```java
    // Query via the expression index to fetch records for customers that are 25 and older
    
    Statement stmt = new Statement();
    
    stmt.setNamespace("test");
    
    stmt.setSetName("cust_data");
    
    // Update the range to start at 25
    
    stmt.setFilter(Filter.rangeByIndex("cust_index", 25, Integer.MAX_VALUE));
    
    try (RecordSet recordSet = client.query(null, stmt)) {
    
        while (recordSet.next()) {
    
            System.out.println(recordSet.getRecord());
    
        }
    
    }
    ```
    
    ```python
    import sys
    
    import aerospike
    
    from aerospike import predicates as p
    
    config = {"hosts": [("127.0.0.1", 3000)]}
    
    client = aerospike.client(config).connect()
    
    # Create a query and apply the new range
    
    q = client.query("test", "cust_data")
    
    q.where_with_index_name("cust_index",
    
                p.range(None, aerospike.INDEX_TYPE_DEFAULT, 25, sys.maxsize))
    
    def handle(record):
    
        key, meta, bins = record
    
        print(bins)
    
    q.foreach(handle)
    
    client.close()
    ```
    
    ```c
    static void
    
    do_query_by_age_at_least_25(aerospike* as)
    
    {
    
      as_query query;
    
      as_query_init(&query, g_namespace, g_set);
    
      as_query_where_init(&query, 1);
    
      as_query_where_with_index_name(&query, "cust_index",
    
                       as_integer_range(25, INT_MAX));
    
      as_error err;
    
      if (aerospike_query_foreach(as, &err, NULL, &query, &query_cb, NULL) !=
    
          AEROSPIKE_OK) {
    
        LOG("aerospike_query_foreach() returned %d - %s", err.code, err.message);
    
        example_cleanup(as);
    
        exit(-1);
    
      }
    
    }
    ```
    
    ```go
    // Query via the expression index to fetch records for customers that are 25 and older
    
    stmt := as.NewStatement("test", "cust_data")
    
    // Update the range to start at 25
    
    stmt.SetFilter(as.NewRangeWithIndexNameFilter("cust_index", 25, math.MaxInt64))
    
    rs, err := client.Query(nil, stmt)
    
    if err != nil {
    
        panic(err)
    
    }
    
    for rec := range rs.Results() {
    
        if rec.Err != nil {
    
            fmt.Printf("error: %v\n", rec.Err)
    
            continue
    
        }
    
        fmt.Println(rec.Record.Bins)
    
    }
    ```
    
    ```c#
    // Query via the expression index to fetch records for customers that are 25 and older
    
    Statement stmt = new();
    
    stmt.SetNamespace("test");
    
    stmt.SetSetName("cust_data");
    
    // Update the range to start at 25
    
    stmt.SetFilter(Filter.RangeByIndex("cust_index", 25, int.MaxValue));
    
    // Execute the query and print the results
    
    try
    
    {
    
        using RecordSet recordSet = client.Query(null, stmt);
    
        while (recordSet.Next())
    
        {
    
            Console.WriteLine(recordSet.Record);
    
        }
    
    }
    ```
    
    ```js
    import Aerospike from "aerospike";
    
    const filter = Aerospike.filter;
    
    // Define the namespace and set for the records
    
    const NAMESPACE = "test";
    
    const SET = "cust_data";
    
    const client = await Aerospike.connect({
    
      hosts: "127.0.0.1:3000",
    
    });
    
    // Create a query object
    
    const query = client.query(NAMESPACE, SET);
    
    // Query via the expression index to fetch records for customers that are 25 and older
    
    query.whereWithIndexName(
    
      filter.range(null, 25, Number.MAX_SAFE_INTEGER),
    
      "cust_index",
    
    );
    
    // Execute the query and print the results
    
    const results = await query.results();
    
    for (const result of results) {
    
      console.log(result);
    
    }
    
    await client.close();
    ```
    
6.  That’s it. You’re done!