---
title: "Path expressions"
description: "Learn how to navigate and manipulate nested Maps and Lists in Aerospike using path expressions and CTX selectors."
---

# Path expressions

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

This page describes path expressions functionality.

## Overview

A path expression is a programmatic, type-safe mechanism used to traverse and manipulate [collection data types](https://aerospike.com/docs/develop/data-types/collections/) (CDTs). Expressions are used by Path expression operations (`selectByPath` and `modifyByPath`) to navigate and interact with nested [Map](https://aerospike.com/docs/develop/data-types/collections/map/) and [List](https://aerospike.com/docs/develop/data-types/collections/list/) elements.

Path expressions enhance Aerospike’s capability to retrieve and manipulate data from JSON-like documents. For a tutorial that builds on path expressions with other CDT techniques, see [Working with nested collection data types](https://aerospike.com/docs/develop/expressions/nesting).

### How path expressions relate to other CDT APIs

Aerospike provides three complementary ways to work with nested collection data. **CDT operations** (`ListOperation`, `MapOperation`) act in-place on the record, reading or modifying a single element at a known position. **CDT expressions** (`ListExp`, `MapExp`) evaluate to a typed value and can be composed with other expressions for filtering and computed reads. **Path expressions** extend both models by selecting or modifying **multiple elements at once** using expression-based contexts such as `allChildren()` and `allChildrenWithFilter()`. For a tutorial that builds on all three techniques, see [Working with nested collection data types](https://aerospike.com/docs/develop/expressions/nesting).

## Operations

Path expressions use two server-side operations to interact with nested CDTs. Both execute directly on database nodes, minimizing data transfer between client and server.

-   **`selectByPath`:** reads and selects multiple nested elements matching the developer-defined paths in a single operation. Returns specific subtrees or values rather than the entire record, reducing network traffic and latency. See the [bookstore examples](#bookstore-example) below.
    
-   **`modifyByPath`:** removes or updates the value of matched elements, directly on the server.
    

## Navigation and metadata

Navigation through hierarchical CDT structures is managed through a [context](https://aerospike.com/docs/develop/data-types/collections/context/) list (CTX). The list defines element selection and filtering logic at each level of the document.

### Path selectors

Paths are defined by progressively applying a list of element selectors from the root bin down to the target element(s). Every step must be contiguous.

-   **Index, Key, Rank, Value:** standard single-element selectors that navigate to a specific address within a List or Map.
    
-   **`allChildren()`:** matches all elements in a List or Map, enabling multi-element selection and retrieval. See the [bookstore examples](#the-authors-of-all-books-in-the-store) and [advanced usage](https://aerospike.com/docs/develop/expressions/path/advanced) for worked examples.
    
-   **`allChildrenWithFilter(exp)`:** matches elements that satisfy a filter [expression](https://aerospike.com/docs/develop/expressions). See [filtering books by price](#filter-all-books-cheaper-than-10) for an example.
    

### Loop variables

During path resolution with `allChildrenWithFilter`, a typed loop variable acts as a contextual placeholder that is filled with an aspect of the current CDT element being evaluated:

-   **`MAP_KEY`:** when the current element is a Map, assign its key to the loop var.
-   **`VALUE`:** assign the value of the current (Map or List) element to the loop var.
-   **`LIST_INDEX`:** when the current element is a List, assign its index position to the loop var.

For worked examples using loop variables, see the [advanced usage page](https://aerospike.com/docs/develop/expressions/path/advanced#accessing-current-element-data-from-a-map-key-list-index-or-element-value-with-a-loopvar).

## Return modes

The `selectFlags` parameter determines the format and content of the elements matched by a `selectByPath` operation.

-   **`MATCHING_TREE`:** Returns a hierarchical tree starting from the root down to the target nodes, preserving parent-child relationships. Only branches that satisfied the filter criteria are included. This provides the highest level of structural control.
    
-   **`VALUE` / `VALUES`:** Returns a flat list of values from the final context level.
    
-   **`MAP_KEY` / `MAP_KEYS`:** Returns only the keys of the selected map elements.
    
-   **`NO_FAIL`:** Ignores elements with incompatible types rather than failing the entire operation. Useful when matching across heterogeneous collections where not every element has the expected data type.
    

## Indexing and constraints

-   **Nesting depth:** Aerospike supports up to 15 levels of CDT nesting.
    
-   **Expression indexes:** Path expressions can be combined with [expression indexes](https://aerospike.com/docs/database/learn/tutorials/quick-start-expression-index/) to support high-speed querying into nested documents. See the [expression index example](https://aerospike.com/docs/develop/expressions/nesting#create-an-expression-index-on-license-plates) for a walkthrough.
    
-   **Batch inlining:** For in-memory namespaces with records exceeding about 1KiB, consider setting `allowInline` to `false`. See [performance considerations](https://aerospike.com/docs/develop/expressions/path/performance#batch-inlining-with-large-records) for details.
    

## Language support

Path expressions are supported in Java, Python, C#, C, Go, and Node.js. See the [client feature compatibility matrix](https://aerospike.com/docs/develop/client-matrix#full-clientserver-feature-compatibility) for version details.

## Bookstore example

The examples below use the classic [JSONPath bookstore dataset](https://goessner.net/articles/JsonPath/index.html#e3) to demonstrate path expression queries. The data is stored as a single map bin named `"bookstore"`.

### Data structure

```json
{

  "store": {

    "book": [

      { "category": "reference",

        "author": "Nigel Rees",

        "title": "Sayings of the Century",

        "price": 8.95

      },

      { "category": "fiction",

        "author": "Evelyn Waugh",

        "title": "Sword of Honour",

        "price": 12.99

      },

      { "category": "fiction",

        "author": "Herman Melville",

        "title": "Moby Dick",

        "isbn": "0-553-21311-3",

        "price": 8.99

      },

      { "category": "fiction",

        "author": "J. R. R. Tolkien",

        "title": "The Lord of the Rings",

        "isbn": "0-395-19395-8",

        "price": 22.99

      }

    ],

    "bicycle": {

      "color": "red",

      "price": 19.95

    }

  },

  "expensive": 10

}
```

### Filtering dimensions

```txt
bin "bookstore" (map)

 ├── store (map)

 │    ├── book (list of 4 maps)

 │    │    ├── {category:"reference", author:"Nigel Rees", title:"Sayings of the Century", price:8.95}

 │    │    ├── {category:"fiction", author:"Evelyn Waugh", title:"Sword of Honour", price:12.99}

 │    │    ├── {category:"fiction", author:"Herman Melville", title:"Moby Dick", isbn:"0-553-21311-3", price:8.99}

 │    │    └── {category:"fiction", author:"J. R. R. Tolkien", title:"The Lord of the Rings", isbn:"0-395-19395-8", price:22.99}

 │    └── bicycle (map)

 │         ├── color: "red"

 │         └── price: 19.95

 └── expensive: 10
```

-   **Store level**: select `book` vs `bicycle` (map key navigation)
-   **Book level**: filter on `category`, `author`, `title`, `price`, presence of `isbn`
-   **Cross-level**: compare book `price` against the top-level `expensive` threshold (10)

### The authors of all books in the store

**JSONPath equivalent:** `$.store.book[*].author`

Navigate to the book list, match all children, and select just the `"author"` key from each book map.

-   [Java](#tab-panel-2808)
-   [Python](#tab-panel-2809)
-   [C](#tab-panel-2810)
-   [Go](#tab-panel-2811)
-   [C#](#tab-panel-2812)
-   [Node.js](#tab-panel-2813)

```java
CdtOperation.selectByPath("bookstore", SelectFlags.VALUE,

    CTX.mapKey(Value.get("store")),

    CTX.mapKey(Value.get("book")),

    CTX.allChildren(),

    CTX.mapKey(Value.get("author")));
```

```python
ctx = [

    cdt_ctx.cdt_ctx_map_key("store"),

    cdt_ctx.cdt_ctx_map_key("book"),

    cdt_ctx.cdt_ctx_all_children(),

    cdt_ctx.cdt_ctx_map_key("author"),

]

ops = [

    operations.select_by_path(

        bin_name="bookstore", ctx=ctx,

        flags=aerospike.EXP_PATH_SELECT_VALUE)

]

_, _, bins = client.operate(key, ops)
```

```c
as_cdt_ctx ctx;

as_cdt_ctx_inita(&ctx, 4);

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("store", false));

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("book", false));

as_cdt_ctx_add_all_children(&ctx);

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("author", false));

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_select_by_path(&err, &ops, "bookstore", &ctx,

    AS_EXP_PATH_SELECT_VALUE);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```go
record, err := client.Operate(nil, key,

    as.SelectByPath("bookstore", as.EXP_PATH_SELECT_VALUE,

        as.CtxMapKey(as.NewStringValue("store")),

        as.CtxMapKey(as.NewStringValue("book")),

        as.CtxAllChildren(),

        as.CtxMapKey(as.NewStringValue("author"))),

)
```

```csharp
Record record = client.Operate(null, key,

    CDTOperation.SelectByPath("bookstore", SelectFlag.VALUE,

        CTX.MapKey(Value.Get("store")),

        CTX.MapKey(Value.Get("book")),

        CTX.AllChildren(),

        CTX.MapKey(Value.Get("author")))

);
```

```js
const context = new Context()

  .addMapKey('store')

  .addMapKey('book')

  .addAllChildren()

  .addMapKey('author')

const ops = [

  op.selectByPath('bookstore', exp.pathSelectFlags.VALUE, context)

]

const result = await client.operate(key, ops)
```

**Output:**

```json
["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"]
```

### Filter all books with an ISBN number

**JSONPath equivalent:** `$.store.book[?(@.isbn)]`

Filter books where the `isbn` key exists using `MapReturnType.EXISTS`.

-   [Java](#tab-panel-2814)
-   [Python](#tab-panel-2815)
-   [C](#tab-panel-2816)
-   [Go](#tab-panel-2817)
-   [C#](#tab-panel-2818)
-   [Node.js](#tab-panel-2819)

```java
Exp hasIsbn = MapExp.getByKey(MapReturnType.EXISTS, Exp.Type.BOOL,

    Exp.val("isbn"), Exp.mapLoopVar(LoopVarPart.VALUE));

CdtOperation.selectByPath("bookstore", SelectFlags.VALUE,

    CTX.mapKey(Value.get("store")),

    CTX.mapKey(Value.get("book")),

    CTX.allChildrenWithFilter(hasIsbn));
```

```python
has_isbn = exp.MapGetByKey(

    ctx=None,

    return_type=aerospike.MAP_RETURN_EXISTS,

    value_type=exp.ResultType.BOOLEAN,

    key=exp.Val("isbn"),

    bin=exp.LoopVarMap(aerospike.EXP_LOOPVAR_VALUE)

).compile()

ctx = [

    cdt_ctx.cdt_ctx_map_key("store"),

    cdt_ctx.cdt_ctx_map_key("book"),

    cdt_ctx.cdt_ctx_all_children_with_filter(has_isbn),

]

ops = [

    operations.select_by_path(

        bin_name="bookstore", ctx=ctx,

        flags=aerospike.EXP_PATH_SELECT_VALUE)

]

_, _, bins = client.operate(key, ops)
```

```c
as_exp_build(has_isbn,

    as_exp_map_get_by_key(NULL, AS_MAP_RETURN_EXISTS, AS_EXP_TYPE_BOOL,

        as_exp_str("isbn"),

        as_exp_loopvar_map(AS_EXP_LOOPVAR_VALUE))

);

as_cdt_ctx ctx;

as_cdt_ctx_inita(&ctx, 3);

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("store", false));

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("book", false));

as_cdt_ctx_add_all_children_with_filter(&ctx, has_isbn);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_select_by_path(&err, &ops, "bookstore", &ctx,

    AS_EXP_PATH_SELECT_VALUE);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```go
hasIsbn := as.ExpMapGetByKey(

    as.MapReturnType.EXISTS, as.ExpTypeBOOL,

    as.ExpStringVal("isbn"),

    as.ExpMapLoopVar(as.VALUE),

)

record, err := client.Operate(nil, key,

    as.SelectByPath("bookstore", as.EXP_PATH_SELECT_VALUE,

        as.CtxMapKey(as.NewStringValue("store")),

        as.CtxMapKey(as.NewStringValue("book")),

        as.CtxAllChildrenWithFilter(hasIsbn)),

)
```

```csharp
Exp hasIsbn = MapExp.GetByKey(MapReturnType.EXISTS, Exp.Type.BOOL,

    Exp.Val("isbn"), Exp.MapLoopVar(LoopVarPart.VALUE));

Record record = client.Operate(null, key,

    CDTOperation.SelectByPath("bookstore", SelectFlag.VALUE,

        CTX.MapKey(Value.Get("store")),

        CTX.MapKey(Value.Get("book")),

        CTX.AllChildrenWithFilter(hasIsbn))

);
```

```js
const hasIsbn = exp.maps.getByKey(

  exp.loopVarMap(exp.loopVarPart.VALUE),

  exp.str('isbn'),

  exp.type.BOOL,

  maps.returnType.EXISTS

)

const context = new Context()

  .addMapKey('store')

  .addMapKey('book')

  .addAllChildrenWithFilter(hasIsbn)

const ops = [

  op.selectByPath('bookstore', exp.pathSelectFlags.VALUE, context)

]

const result = await client.operate(key, ops)
```

**Output:**

```json
[

  {"category":"fiction", "author":"Herman Melville", "title":"Moby Dick", "isbn":"0-553-21311-3", "price":8.99},

  {"category":"fiction", "author":"J. R. R. Tolkien", "title":"The Lord of the Rings", "isbn":"0-395-19395-8", "price":22.99}

]
```

### Filter all books cheaper than 10

**JSONPath equivalent:** `$.store.book[?(@.price < 10)]`

-   [Java](#tab-panel-2820)
-   [Python](#tab-panel-2821)
-   [C](#tab-panel-2822)
-   [Go](#tab-panel-2823)
-   [C#](#tab-panel-2824)
-   [Node.js](#tab-panel-2825)

```java
Exp cheapBooks = Exp.lt(

    MapExp.getByKey(MapReturnType.VALUE, Exp.Type.FLOAT,

        Exp.val("price"), Exp.mapLoopVar(LoopVarPart.VALUE)),

    Exp.val(10.0));

CdtOperation.selectByPath("bookstore", SelectFlags.VALUE,

    CTX.mapKey(Value.get("store")),

    CTX.mapKey(Value.get("book")),

    CTX.allChildrenWithFilter(cheapBooks));
```

```python
cheap_books = exp.LT(

    exp.MapGetByKey(

        ctx=None,

        return_type=aerospike.MAP_RETURN_VALUE,

        value_type=exp.ResultType.FLOAT,

        key=exp.Val("price"),

        bin=exp.LoopVarMap(aerospike.EXP_LOOPVAR_VALUE)

    ),

    exp.Val(10.0)

).compile()

ctx = [

    cdt_ctx.cdt_ctx_map_key("store"),

    cdt_ctx.cdt_ctx_map_key("book"),

    cdt_ctx.cdt_ctx_all_children_with_filter(cheap_books),

]

ops = [

    operations.select_by_path(

        bin_name="bookstore", ctx=ctx,

        flags=aerospike.EXP_PATH_SELECT_VALUE)

]

_, _, bins = client.operate(key, ops)
```

```c
as_exp_build(cheap_books,

    as_exp_cmp_lt(

        as_exp_map_get_by_key(NULL, AS_MAP_RETURN_VALUE, AS_EXP_TYPE_FLOAT,

            as_exp_str("price"),

            as_exp_loopvar_map(AS_EXP_LOOPVAR_VALUE)),

        as_exp_float(10.0))

);

as_cdt_ctx ctx;

as_cdt_ctx_inita(&ctx, 3);

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("store", false));

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("book", false));

as_cdt_ctx_add_all_children_with_filter(&ctx, cheap_books);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_select_by_path(&err, &ops, "bookstore", &ctx,

    AS_EXP_PATH_SELECT_VALUE);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```go
cheapBooks := as.ExpLess(

    as.ExpMapGetByKey(

        as.MapReturnType.VALUE, as.ExpTypeFLOAT,

        as.ExpStringVal("price"),

        as.ExpMapLoopVar(as.VALUE),

    ),

    as.ExpFloatVal(10.0),

)

record, err := client.Operate(nil, key,

    as.SelectByPath("bookstore", as.EXP_PATH_SELECT_VALUE,

        as.CtxMapKey(as.NewStringValue("store")),

        as.CtxMapKey(as.NewStringValue("book")),

        as.CtxAllChildrenWithFilter(cheapBooks)),

)
```

```csharp
Exp cheapBooks = Exp.LT(

    MapExp.GetByKey(MapReturnType.VALUE, Exp.Type.FLOAT,

        Exp.Val("price"), Exp.MapLoopVar(LoopVarPart.VALUE)),

    Exp.Val(10.0));

Record record = client.Operate(null, key,

    CDTOperation.SelectByPath("bookstore", SelectFlag.VALUE,

        CTX.MapKey(Value.Get("store")),

        CTX.MapKey(Value.Get("book")),

        CTX.AllChildrenWithFilter(cheapBooks))

);
```

```js
const cheapBooks = exp.lt(

  exp.maps.getByKey(

    exp.loopVarMap(exp.loopVarPart.VALUE),

    exp.str('price'),

    exp.type.FLOAT,

    maps.returnType.VALUE

  ),

  exp.float(10.0)

)

const context = new Context()

  .addMapKey('store')

  .addMapKey('book')

  .addAllChildrenWithFilter(cheapBooks)

const ops = [

  op.selectByPath('bookstore', exp.pathSelectFlags.VALUE, context)

]

const result = await client.operate(key, ops)
```

**Output:**

```json
[

  {"category":"reference", "author":"Nigel Rees", "title":"Sayings of the Century", "price":8.95},

  {"category":"fiction", "author":"Herman Melville", "title":"Moby Dick", "isbn":"0-553-21311-3", "price":8.99}

]
```

### Filter all fiction books costing less than 10

**JSONPath equivalent:** `$.store.book[?(@.category=='fiction' && @.price < 10)]`

Compound filter combining two conditions with `Exp.and()`.

-   [Java](#tab-panel-2826)
-   [Python](#tab-panel-2827)
-   [C](#tab-panel-2828)
-   [Go](#tab-panel-2829)
-   [C#](#tab-panel-2830)
-   [Node.js](#tab-panel-2831)

```java
Exp isFiction = Exp.eq(

    MapExp.getByKey(MapReturnType.VALUE, Exp.Type.STRING,

        Exp.val("category"), Exp.mapLoopVar(LoopVarPart.VALUE)),

    Exp.val("fiction"));

Exp cheapBooks = Exp.lt(

    MapExp.getByKey(MapReturnType.VALUE, Exp.Type.FLOAT,

        Exp.val("price"), Exp.mapLoopVar(LoopVarPart.VALUE)),

    Exp.val(10.0));

CdtOperation.selectByPath("bookstore", SelectFlags.VALUE,

    CTX.mapKey(Value.get("store")),

    CTX.mapKey(Value.get("book")),

    CTX.allChildrenWithFilter(Exp.and(isFiction, cheapBooks)));
```

```python
is_fiction = exp.Eq(

    exp.MapGetByKey(

        ctx=None,

        return_type=aerospike.MAP_RETURN_VALUE,

        value_type=exp.ResultType.STRING,

        key=exp.Val("category"),

        bin=exp.LoopVarMap(aerospike.EXP_LOOPVAR_VALUE)

    ),

    exp.Val("fiction")

)

cheap_books = exp.LT(

    exp.MapGetByKey(

        ctx=None,

        return_type=aerospike.MAP_RETURN_VALUE,

        value_type=exp.ResultType.FLOAT,

        key=exp.Val("price"),

        bin=exp.LoopVarMap(aerospike.EXP_LOOPVAR_VALUE)

    ),

    exp.Val(10.0)

)

combined = exp.And(is_fiction, cheap_books).compile()

ctx = [

    cdt_ctx.cdt_ctx_map_key("store"),

    cdt_ctx.cdt_ctx_map_key("book"),

    cdt_ctx.cdt_ctx_all_children_with_filter(combined),

]

ops = [

    operations.select_by_path(

        bin_name="bookstore", ctx=ctx,

        flags=aerospike.EXP_PATH_SELECT_VALUE)

]

_, _, bins = client.operate(key, ops)
```

```c
as_exp_build(filter,

    as_exp_and(

        as_exp_cmp_eq(

            as_exp_map_get_by_key(NULL, AS_MAP_RETURN_VALUE, AS_EXP_TYPE_STR,

                as_exp_str("category"),

                as_exp_loopvar_map(AS_EXP_LOOPVAR_VALUE)),

            as_exp_str("fiction")),

        as_exp_cmp_lt(

            as_exp_map_get_by_key(NULL, AS_MAP_RETURN_VALUE, AS_EXP_TYPE_FLOAT,

                as_exp_str("price"),

                as_exp_loopvar_map(AS_EXP_LOOPVAR_VALUE)),

            as_exp_float(10.0)))

);

as_cdt_ctx ctx;

as_cdt_ctx_inita(&ctx, 3);

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("store", false));

as_cdt_ctx_add_map_key(&ctx, (as_val*)as_string_new("book", false));

as_cdt_ctx_add_all_children_with_filter(&ctx, filter);

as_operations ops;

as_operations_inita(&ops, 1);

as_operations_select_by_path(&err, &ops, "bookstore", &ctx,

    AS_EXP_PATH_SELECT_VALUE);

as_record* rec = NULL;

aerospike_key_operate(&as, &err, NULL, &key, &ops, &rec);
```

```go
isFiction := as.ExpEq(

    as.ExpMapGetByKey(

        as.MapReturnType.VALUE, as.ExpTypeSTR,

        as.ExpStringVal("category"),

        as.ExpMapLoopVar(as.VALUE),

    ),

    as.ExpStringVal("fiction"),

)

cheapBooks := as.ExpLess(

    as.ExpMapGetByKey(

        as.MapReturnType.VALUE, as.ExpTypeFLOAT,

        as.ExpStringVal("price"),

        as.ExpMapLoopVar(as.VALUE),

    ),

    as.ExpFloatVal(10.0),

)

record, err := client.Operate(nil, key,

    as.SelectByPath("bookstore", as.EXP_PATH_SELECT_VALUE,

        as.CtxMapKey(as.NewStringValue("store")),

        as.CtxMapKey(as.NewStringValue("book")),

        as.CtxAllChildrenWithFilter(as.ExpAnd(isFiction, cheapBooks))),

)
```

```csharp
Exp isFiction = Exp.EQ(

    MapExp.GetByKey(MapReturnType.VALUE, Exp.Type.STRING,

        Exp.Val("category"), Exp.MapLoopVar(LoopVarPart.VALUE)),

    Exp.Val("fiction"));

Exp cheapBooks = Exp.LT(

    MapExp.GetByKey(MapReturnType.VALUE, Exp.Type.FLOAT,

        Exp.Val("price"), Exp.MapLoopVar(LoopVarPart.VALUE)),

    Exp.Val(10.0));

Record record = client.Operate(null, key,

    CDTOperation.SelectByPath("bookstore", SelectFlag.VALUE,

        CTX.MapKey(Value.Get("store")),

        CTX.MapKey(Value.Get("book")),

        CTX.AllChildrenWithFilter(Exp.And(isFiction, cheapBooks)))

);
```

```js
const isFiction = exp.eq(

  exp.maps.getByKey(

    exp.loopVarMap(exp.loopVarPart.VALUE),

    exp.str('category'),

    exp.type.STR,

    maps.returnType.VALUE

  ),

  exp.str('fiction')

)

const cheapBooks = exp.lt(

  exp.maps.getByKey(

    exp.loopVarMap(exp.loopVarPart.VALUE),

    exp.str('price'),

    exp.type.FLOAT,

    maps.returnType.VALUE

  ),

  exp.float(10.0)

)

const context = new Context()

  .addMapKey('store')

  .addMapKey('book')

  .addAllChildrenWithFilter(exp.and(isFiction, cheapBooks))

const ops = [

  op.selectByPath('bookstore', exp.pathSelectFlags.VALUE, context)

]

const result = await client.operate(key, ops)
```

**Output:**

```json
[

  {"category":"fiction", "author":"Herman Melville", "title":"Moby Dick", "isbn":"0-553-21311-3", "price":8.99}

]
```

## Next steps

-   Check out the [Quickstart: Path expressions](https://aerospike.com/docs/develop/expressions/path/quickstart).
    
-   Dive deeper with [advanced usage](https://aerospike.com/docs/develop/expressions/path/advanced).
    
-   Find more information in the [FAQ](https://aerospike.com/docs/develop/expressions/path/faq).