
# Path

Access specific elements within a JSON document

Paths let you access specific elements within a JSON document. Since no standard for JSON path syntax exists, Redis JSON implements its own. JSON's syntax is based on common best practices and intentionally resembles [JSONPath](http://goessner.net/articles/JsonPath/).

JSON supports two query syntaxes: [JSONPath syntax](#jsonpath-syntax) and the [legacy path syntax](#legacy-path-syntax) from the first version of JSON.

JSON knows which syntax to use depending on the first character of the path query. If the query starts with the character `$`, it uses JSONPath syntax. Otherwise, it defaults to the legacy path syntax.

The returned value is a JSON string with a top-level array of JSON serialized strings. And if multi-paths are used, the return value is a JSON string with a top-level object with values that are arrays of serialized JSON values.

## JSONPath support

RedisJSON v2.0 introduced [JSONPath](http://goessner.net/articles/JsonPath/) support. It follows the syntax described by Goessner in his [article](http://goessner.net/articles/JsonPath/).

A JSONPath query can resolve to several locations in a JSON document. In this case, the JSON commands apply the operation to every possible location. This is a major improvement over [legacy path](#legacy-path-syntax) queries, which only operate on the first path.

Notice that the structure of the command response often differs when using JSONPath. See the [Commands](/docs/latest/commands/?group=json) page for more details.

The new syntax supports bracket notation, which allows the use of special characters like colon ":" or whitespace in key names.

If you want to include double quotes in a query from the CLI, enclose the JSONPath within single quotes. For example:

```bash
JSON.GET store '$.inventory["mountain_bikes"]'
```

## JSONPath syntax

The following JSONPath syntax table was adapted from Goessner's [path syntax comparison](https://goessner.net/articles/JsonPath/index.html#e2).

Syntax element

Description

$

The root (outermost JSON element), starts the path.

. or \[\]

Selects a child element.

..

Recursively descends through the JSON document.

\*

Wildcard, returns all elements.

\[\]

Subscript operator, accesses an array element.

\[,\]

Union, selects multiple elements.

\[start:end:step\]

Array slice where _start_, _end_, and _step_ are index values. You can omit values from the slice (for example, `[3:]`, `[:8:2]`) to use the default values: _start_ defaults to the first index, _end_ defaults to the last index, and _step_ defaults to `1`. Use `[*]` or `[:]` to select all elements.

?()

Filters a JSON object or array. Supports comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`, `=~`), logical operators (`&&`, `||`), and parenthesis (`(`, `)`).

()

Script expression.

@

The current element, used in filter or script expressions.

## JSONPath examples

The following JSONPath examples use this JSON document, which stores details about items in a store's inventory:

```json
{
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}
```

First, create the JSON document in your database:

```plaintext
> JSON.SET bikes:inventory $ '{ "inventory": { "mountain_bikes": [ { "id": "bike:1", "model": "Phoebe", "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\'s room for mudguards and a rack too. This is the bike for the rider who wants trail manners with low fuss ownership.", "price": 1920, "specs": {"material": "carbon", "weight": 13.1}, "colors": ["black", "silver"] }, { "id": "bike:2", "model": "Quaoar", "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we\'ve ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it\'s an impressive package for the price, making it very competitive.", "price": 2072, "specs": {"material": "aluminium", "weight": 7.9}, "colors": ["black", "white"] }, { "id": "bike:3", "model": "Weywot", "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.", "price": 3264, "specs": {"material": "alloy", "weight": 13.8} } ], "commuter_bikes": [ { "id": "bike:4", "model": "Salacia", "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\'s, this is a bike which doesn\'t break the bank and delivers craved performance. It\'s for the rider who wants both efficiency and capability.", "price": 1475, "specs": {"material": "aluminium", "weight": 16.6}, "colors": ["black", "silver"] }, { "id": "bike:5", "model": "Mimas", "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.", "price": 3941, "specs": {"material": "alloy", "weight": 11.6} } ] }}'
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

### Access examples

The following examples use the [`JSON.GET`](/docs/latest/commands/json.get/) command to retrieve data from various paths in the JSON document.

You can use the wildcard operator `*` to return a list of all items in the inventory:

```plaintext
> JSON.GET bikes:inventory $.inventory.*
"[[{\"id\":\"bike:1\",\"model\":\"Phoebe\",\"description\":\"This is a mid-travel trail slayer...
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

For some queries, multiple paths can produce the same results. For example, the following paths return the names of all mountain bikes:

```plaintext
> JSON.GET bikes:inventory $.inventory.mountain_bikes[*].model
"[\"Phoebe\",\"Quaoar\",\"Weywot\"]"
> JSON.GET bikes:inventory '$.inventory["mountain_bikes"][*].model'
"[\"Phoebe\",\"Quaoar\",\"Weywot\"]"
> JSON.GET bikes:inventory '$..mountain_bikes[*].model'
"[\"Phoebe\",\"Quaoar\",\"Weywot\"]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

The recursive descent operator `..` can retrieve a field from multiple sections of a JSON document. The following example returns the names of all inventory items:

```plaintext
> JSON.GET bikes:inventory $..model
"[\"Phoebe\",\"Quaoar\",\"Weywot\",\"Salacia\",\"Mimas\"]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

You can use an array slice to select a range of elements from an array. This example returns the names of the first 2 mountain bikes:

```plaintext
> JSON.GET bikes:inventory $..mountain_bikes[0:2].model
"[\"Phoebe\",\"Quaoar\"]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

Filter expressions `?()` let you select JSON elements based on certain conditions. You can use comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`, and starting with version v2.4.2, also `=~`), logical operators (`&&`, `||`), and parenthesis (`(`, `)`) within these expressions. A filter expression can be applied on an array or on an object, iterating over all the **elements** in the array or all the **values** in the object, retrieving only the ones that match the filter condition.

Paths within the filter condition use the dot notation with either `@` to denote the current array element or the current object value, or `$` to denote the top-level element. For example, use `@.key_name` to refer to a nested value and `$.top_level_key_name` to refer to a top-level value.

From version v2.4.2 onward, you can use the comparison operator `=~` to match a path of a string value on the left side against a regular expression pattern on the right side. For more information, see the [supported regular expression syntax docs](https://docs.rs/regex/latest/regex/#syntax).

Non-string values do not match. A match can only occur when the left side is a path of a string value and the right side is either a hard-coded string, or a path of a string value. See [examples](#json-filter-examples) below.

The regex match is partial, meaning a regex pattern like `"foo"` matches a string such as `"barefoots"`. To make the match exact, use the regex pattern `"^foo$"`.

Other JSONPath engines may use regex patterns between slashes (for example, `/foo/`), and their match is exact. They can perform partial matches using a regex pattern such as `/.*foo.*/`.

### Filter examples

In the following example, the filter only returns mountain bikes with a price less than 3000 and a weight less than 10:

```plaintext
> JSON.GET bikes:inventory '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
"[{\"id\":\"bike:2\",\"model\":\"Quaoar\",\"description\":\"Redesigned for the 2020 model year...
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

This example filters the inventory for the model names of bikes made from alloy:

```plaintext
> JSON.GET bikes:inventory '$..[?(@.specs.material == "alloy")].model'
"[\"Weywot\",\"Mimas\"]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

This example, valid from version v2.4.2 onwards, filters only bikes whose material begins with "al-" using regex match. Note that this match is case-insensitive because of the prefix `(?i)` in the regular expression pattern `"(?i)al"`:

```plaintext
JSON.GET bikes:inventory '$..[?(@.specs.material =~ "(?i)al")].model'
"[\"Quaoar\",\"Weywot\",\"Salacia\",\"Mimas\"]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

You can also specify a regex pattern using a property from the JSON object itself. For example, we can add a string property named `regex_pat` to each mountain bike, with the value `"(?i)al"` to match the material, as in the previous example. We can then match `regex_pat` against the bike's material:

```plaintext
> JSON.SET bikes:inventory $.inventory.mountain_bikes[0].regex_pat '"(?i)al"'
OK
> JSON.SET bikes:inventory $.inventory.mountain_bikes[1].regex_pat '"(?i)al"'
OK
> JSON.SET bikes:inventory $.inventory.mountain_bikes[2].regex_pat '"(?i)al"'
OK
> JSON.GET bikes:inventory '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
"[\"Quaoar\",\"Weywot\"]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

### Update examples

You can also use JSONPath queries when you want to update specific sections of a JSON document.

For example, you can pass a JSONPath to the [`JSON.SET`](/docs/latest/commands/json.set/) command to update a specific field. This example changes the price of the first item in the headphones list:

```plaintext
> JSON.GET bikes:inventory $..price
"[1920,2072,3264,1475,3941]"
> JSON.NUMINCRBY bikes:inventory $..price -100
"[1820,1972,3164,1375,3841]"
> JSON.NUMINCRBY bikes:inventory $..price 100
"[1920,2072,3264,1475,3941]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

You can use filter expressions to update only JSON elements that match certain conditions. The following example sets the price of any bike to 1500 if its price is already less than 2000:

```plaintext
> JSON.SET bikes:inventory '$.inventory.*[?(@.price<2000)].price' 1500
OK
> JSON.GET bikes:inventory $..price
"[1500,2072,3264,1500,3941]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

JSONPath queries also work with other JSON commands that accept a path as an argument. For example, you can add a new color option for a set of headphones with [`JSON.ARRAPPEND`](/docs/latest/commands/json.arrappend/):

```plaintext
> JSON.ARRAPPEND bikes:inventory '$.inventory.*[?(@.price<2000)].colors' '"pink"'
1) (integer) 3
2) (integer) 3
127.0.0.1:6379> JSON.GET bikes:inventory $..[*].colors
"[[\"black\",\"silver\",\"pink\"],[\"black\",\"white\"],[\"black\",\"silver\",\"pink\"]]"
```

```python
"""
Code samples for JSON doc pages:
    https://redis.io/docs/latest/develop/data-types/json/
"""
import redis

r = redis.Redis(decode_responses=True)

res1 = r.json().set("bike", "$", '"Hyperion"')
print(res1)  # >>> True

res2 = r.json().get("bike", "$")
print(res2)  # >>> ['"Hyperion"']

res3 = r.json().type("bike", "$")
print(res3)  # >>> ['string']

res4 = r.json().strlen("bike", "$")
print(res4)  # >>> [10]

res5 = r.json().strappend("bike", '" (Enduro bikes)"')
print(res5)  # >>> 27

res6 = r.json().get("bike", "$")
print(res6)  # >>> ['"Hyperion"" (Enduro bikes)"']

res7 = r.json().set("crashes", "$", 0)
print(res7)  # >>> True

res8 = r.json().numincrby("crashes", "$", 1)
print(res8)  # >>> [1]

res9 = r.json().numincrby("crashes", "$", 1.5)
print(res9)  # >>> [2.5]

res10 = r.json().numincrby("crashes", "$", -0.75)
print(res10)  # >>> [1.75]

res11 = r.json().set("newbike", "$", ["Deimos", {"crashes": 0}, None])
print(res11)  # >>> True

res12 = r.json().get("newbike", "$")
print(res12)  # >>> ['["Deimos", { "crashes": 0 }, null]']

res13 = r.json().get("newbike", "$[1].crashes")
print(res13)  # >>> [0]

res14 = r.json().delete("newbike", "$.[-1]")
print(res14)  # >>> [1]

res15 = r.json().get("newbike", "$")
print(res15)  # >>> [['Deimos', {'crashes': 0}]]

res16 = r.json().set("riders", "$", [])
print(res16)  # >>> True

res17 = r.json().arrappend("riders", "$", "Norem")
print(res17)  # >>> [1]

res18 = r.json().get("riders", "$")
print(res18)  # >>> [['Norem']]

res19 = r.json().arrinsert("riders", "$", 1, "Prickett", "Royce", "Castilla")
print(res19)  # >>> [4]

res20 = r.json().get("riders", "$")
print(res20)  # >>> [['Norem', 'Prickett', 'Royce', 'Castilla']]

res21 = r.json().arrtrim("riders", "$", 1, 1)
print(res21)  # >>> [1]

res22 = r.json().get("riders", "$")
print(res22)  # >>> [['Prickett']]

res23 = r.json().arrpop("riders", "$")
print(res23)  # >>> ['"Prickett"']

res24 = r.json().arrpop("riders", "$")
print(res24)  # >>> [None]

res25 = r.json().set(
    "bike:1", "$", {"model": "Deimos", "brand": "Ergonom", "price": 4972}
)
print(res25)  # >>> True

res26 = r.json().objlen("bike:1", "$")
print(res26)  # >>> [3]

res27 = r.json().objkeys("bike:1", "$")
print(res27)  # >>> [['model', 'brand', 'price']]

inventory_json = {
    "inventory": {
        "mountain_bikes": [
            {
                "id": "bike:1",
                "model": "Phoebe",
                "description": "This is a mid-travel trail slayer that is a fantastic "
                "daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                "gives plenty of gear range to tackle hills and there\u2019s room for "
                "mudguards and a rack too.  This is the bike for the rider who wants "
                "trail manners with low fuss ownership.",
                "price": 1920,
                "specs": {"material": "carbon", "weight": 13.1},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:2",
                "model": "Quaoar",
                "description": "Redesigned for the 2020 model year, this bike "
                "impressed our testers and is the best all-around trail bike we've "
                "ever tested. The Shimano gear system effectively does away with an "
                "external cassette, so is super low maintenance in terms of wear "
                "and tear. All in all it's an impressive package for the price, "
                "making it very competitive.",
                "price": 2072,
                "specs": {"material": "aluminium", "weight": 7.9},
                "colors": ["black", "white"],
            },
            {
                "id": "bike:3",
                "model": "Weywot",
                "description": "This bike gives kids aged six years and older "
                "a durable and uberlight mountain bike for their first experience "
                "on tracks and easy cruising through forests and fields. A set of "
                "powerful Shimano hydraulic disc brakes provide ample stopping "
                "ability. If you're after a budget option, this is one of the best "
                "bikes you could get.",
                "price": 3264,
                "specs": {"material": "alloy", "weight": 13.8},
            },
        ],
        "commuter_bikes": [
            {
                "id": "bike:4",
                "model": "Salacia",
                "description": "This bike is a great option for anyone who just "
                "wants a bike to get about on With a slick-shifting Claris gears "
                "from Shimano\u2019s, this is a bike which doesn\u2019t break the "
                "bank and delivers craved performance.  It\u2019s for the rider "
                "who wants both efficiency and capability.",
                "price": 1475,
                "specs": {"material": "aluminium", "weight": 16.6},
                "colors": ["black", "silver"],
            },
            {
                "id": "bike:5",
                "model": "Mimas",
                "description": "A real joy to ride, this bike got very high "
                "scores in last years Bike of the year report. The carefully "
                "crafted 50-34 tooth chainset and 11-32 tooth cassette give an "
                "easy-on-the-legs bottom gear for climbing, and the high-quality "
                "Vittoria Zaffiro tires give balance and grip.It includes "
                "a low-step frame , our memory foam seat, bump-resistant shocks and "
                "conveniently placed thumb throttle. Put it all together and you "
                "get a bike that helps redefine what can be done for this price.",
                "price": 3941,
                "specs": {"material": "alloy", "weight": 11.6},
            },
        ],
    }
}

res1 = r.json().set("bikes:inventory", "$", inventory_json)
print(res1)  # >>> True

res2 = r.json().get("bikes:inventory", "$.inventory.*")
print(res2)
# >>>    [[{'id': 'bike:1', 'model': 'Phoebe',
# >>>       'description': 'This is a mid-travel trail slayer...

res3 = r.json().get("bikes:inventory", "$.inventory.mountain_bikes[*].model")
print(res3)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res4 = r.json().get("bikes:inventory", '$.inventory["mountain_bikes"][*].model')
print(res4)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res5 = r.json().get("bikes:inventory", "$..mountain_bikes[*].model")
print(res5)  # >>> [['Phoebe', 'Quaoar', 'Weywot']]

res6 = r.json().get("bikes:inventory", "$..model")
print(res6)  # >>> [['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']]

res7 = r.json().get("bikes:inventory", "$..mountain_bikes[0:2].model")
print(res7)  # >>> [['Phoebe', 'Quaoar']]

res8 = r.json().get(
    "bikes:inventory",
    "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
)
print(res8)
# >>> [{'id': 'bike:2', 'model': 'Quaoar',
#           'description': "Redesigned for the 2020 model year...

res9 = r.json().get("bikes:inventory", "$..[?(@.specs.material == 'alloy')].model")
print(res9)  # >>> ['Weywot', 'Mimas']

res10 = r.json().get("bikes:inventory", "$..[?(@.specs.material =~ '(?i)al')].model")
print(res10)  # >>> ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

res11 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[0].regex_pat", "(?i)al"
)
res12 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[1].regex_pat", "(?i)al"
)
res13 = r.json().set(
    "bikes:inventory", "$.inventory.mountain_bikes[2].regex_pat", "(?i)al"
)

res14 = r.json().get(
    "bikes:inventory",
    "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
)
print(res14)  # >>> ['Quaoar', 'Weywot']

res15 = r.json().get("bikes:inventory", "$..price")
print(res15)  # >>> [1920, 2072, 3264, 1475, 3941]

res16 = r.json().numincrby("bikes:inventory", "$..price", -100)
print(res16)  # >>> [1820, 1972, 3164, 1375, 3841]

res17 = r.json().numincrby("bikes:inventory", "$..price", 100)
print(res17)  # >>> [1920, 2072, 3264, 1475, 3941]

res18 = r.json().set("bikes:inventory", "$.inventory.*[?(@.price<2000)].price", 1500)
res19 = r.json().get("bikes:inventory", "$..price")
print(res19)  # >>> [1500, 2072, 3264, 1500, 3941]

res20 = r.json().arrappend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
)
print(res20)  # >>> [3, 3]

res21 = r.json().get("bikes:inventory", "$..[*].colors")
print(
    res21
)  # >>> [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```node.js
import assert from 'assert';
import {
  createClient
} from 'redis';

const client = await createClient();
await client.connect();

const res1 = await client.json.set("bike", "$", '"Hyperion"');
console.log(res1); // OK

const res2 = await client.json.get("bike", { path: "$" });
console.log(res2); // ['"Hyperion"']

const res3 = await client.json.type("bike", { path: "$" });
console.log(res3); //  [ 'string' ]

const res4 = await client.json.strLen("bike", { path: "$" });
console.log(res4) //  [10]

const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"');
console.log(res5) //  27

const res6 = await client.json.get("bike", { path: "$" });
console.log(res6) //  ['"Hyperion"" (Enduro bikes)"']

const res7 = await client.json.set("crashes", "$", 0);
console.log(res7) //  OK

const res8 = await client.json.numIncrBy("crashes", "$", 1);
console.log(res8) //  [1]

const res9 = await client.json.numIncrBy("crashes", "$", 1.5);
console.log(res9) //  [2.5]

const res10 = await client.json.numIncrBy("crashes", "$", -0.75);
console.log(res10) //  [1.75]

const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]);
console.log(res11); //  OK

const res12 = await client.json.get("newbike", { path: "$" });
console.log(res12); //  [[ 'Deimos', { crashes: 0 }, null ]]

const res13 = await client.json.get("newbike", { path: "$[1].crashes" });
console.log(res13); //  [0]

const res14 = await client.json.del("newbike", { path: "$.[-1]"} );
console.log(res14); //  1

const res15 = await client.json.get("newbike", { path: "$" });
console.log(res15); //  [[ 'Deimos', { crashes: 0 } ]]

const res16 = await client.json.set("riders", "$", []);
console.log(res16); //  OK

const res17 = await client.json.arrAppend("riders", "$", "Norem");
console.log(res17); //  [1]

const res18 = await client.json.get("riders", { path: "$" });
console.log(res18); //  [[ 'Norem' ]]

const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla");
console.log(res19); //  [4]

const res20 = await client.json.get("riders", { path: "$" });
console.log(res20); //  [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]]

const res21 = await client.json.arrTrim("riders", "$", 1, 1);
console.log(res21); //  [1]

const res22 = await client.json.get("riders", { path: "$" });
console.log(res22); //  [[ 'Prickett' ]]

const res23 = await client.json.arrPop("riders", { path: "$" });
console.log(res23); //  [ 'Prickett' ]

const res24 = await client.json.arrPop("riders", { path: "$" });
console.log(res24); //  [null]

const res25 = await client.json.set(
  "bike:1", "$", {
    "model": "Deimos",
    "brand": "Ergonom",
    "price": 4972
  }
);
console.log(res25); //  OK

const res26 = await client.json.objLen("bike:1", { path: "$" });
console.log(res26); //  [3]

const res27 = await client.json.objKeys("bike:1", { path: "$" });
console.log(res27); //  [['model', 'brand', 'price']]

const inventoryJSON = {
  "inventory": {
    "mountain_bikes": [{
        "id": "bike:1",
        "model": "Phoebe",
        "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.",
        "price": 1920,
        "specs": {
          "material": "carbon",
          "weight": 13.1
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:2",
        "model": "Quaoar",
        "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
        "price": 2072,
        "specs": {
          "material": "aluminium",
          "weight": 7.9
        },
        "colors": ["black", "white"],
      },
      {
        "id": "bike:3",
        "model": "Weywot",
        "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
        "price": 3264,
        "specs": {
          "material": "alloy",
          "weight": 13.8
        },
      },
    ],
    "commuter_bikes": [{
        "id": "bike:4",
        "model": "Salacia",
        "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability.",
        "price": 1475,
        "specs": {
          "material": "aluminium",
          "weight": 16.6
        },
        "colors": ["black", "silver"],
      },
      {
        "id": "bike:5",
        "model": "Mimas",
        "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.",
        "price": 3941,
        "specs": {
          "material": "alloy",
          "weight": 11.6
        },
      },
    ],
  }
};

const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON);
console.log(res28); //  OK

const res29 = await client.json.get("bikes:inventory", {
  path: "$.inventory.*"
});
console.log(res29);
/*
[
  [
    {
      id: 'bike:1',
      model: 'Phoebe',
      description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
      price: 1920,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:2',
      model: 'Quaoar',
      description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
      price: 2072,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:3',
      model: 'Weywot',
      description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.",
      price: 3264,
      specs: [Object]
    }
  ],
  [
    {
      id: 'bike:4',
      model: 'Salacia',
      description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
      price: 1475,
      specs: [Object],
      colors: [Array]
    },
    {
      id: 'bike:5',
      model: 'Mimas',
      description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
      price: 3941,
      specs: [Object]
    }
  ]
]
*/

const res30 = await client.json.get("bikes:inventory", {
  path: "$.inventory.mountain_bikes[*].model"
});
console.log(res30); //  ['Phoebe', 'Quaoar', 'Weywot']

const res31 = await client.json.get("bikes:inventory", {
  path: '$.inventory["mountain_bikes"][*].model'
});
console.log(res31); //  ['Phoebe', 'Quaoar', 'Weywot']

const res32 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[*].model"
});
console.log(res32); //  ['Phoebe', 'Quaoar', 'Weywot']

const res33 = await client.json.get("bikes:inventory", {
  path: "$..model"
});
console.log(res33); //  ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res34 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[0:2].model"
});
console.log(res34); //  ['Phoebe', 'Quaoar']

const res35 = await client.json.get("bikes:inventory", {
  path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
});
console.log(res35);
/*
[
  {
    id: 'bike:2',
    model: 'Quaoar',
    description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.",
    price: 2072,
    specs: { material: 'aluminium', weight: 7.9 },
    colors: [ 'black', 'white' ]
  }
]
*/

//  names of bikes made from an alloy
const res36 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material == 'alloy')].model"
});
console.log(res36); //  ['Weywot', 'Mimas']

const res37 = await client.json.get("bikes:inventory", {
  path: "$..[?(@.specs.material =~ '(?i)al')].model"
});
console.log(res37); //  ['Quaoar', 'Weywot', 'Salacia', 'Mimas']

const res37a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[0].regex_pat', 
  '(?i)al'
);

const res37b = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[1].regex_pat', 
  '(?i)al'
);

const res37c = await client.json.set(
  'bikes:inventory', 
  '$.inventory.mountain_bikes[2].regex_pat', 
  '(?i)al'
);

const res37d = await client.json.get(
  'bikes:inventory',
  { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' }
);
console.log(res37d); // ['Quaoar', 'Weywot']

const res38 = await client.json.get("bikes:inventory", {
  path: "$..price"
});
console.log(res38);  //  [1920, 2072, 3264, 1475, 3941]

const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100);
console.log(res39);  //  [1820, 1972, 3164, 1375, 3841]

const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100);
console.log(res40);  //  [1920, 2072, 3264, 1475, 3941]

const res40a = await client.json.set(
  'bikes:inventory', 
  '$.inventory.*[?(@.price<2000)].price', 
  1500
);

// Get all prices from the inventory
const res40b = await client.json.get(
  'bikes:inventory',
  { path: "$..price" }
);
console.log(res40b); // [1500, 2072, 3264, 1500, 3941]

const res41 = await client.json.arrAppend(
    "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
);
console.log(res41);  //  [3, 3]

const res42 = await client.json.get("bikes:inventory", {
  path: "$..[*].colors"
});
console.log(res42);  //  [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']]

```

```java

import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.json.Path2;

import org.json.JSONArray;
import org.json.JSONObject;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class JsonExample {
    public void run() {
        UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");

        String res1 = jedis.jsonSet("bike", new Path2("$"), "\"Hyperion\"");
        System.out.println(res1);   // >>> OK

        Object res2 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res2);   // >>> ["Hyperion"]

        List<Class<?>> res3 = jedis.jsonType("bike", new Path2("$"));
        System.out.println(res3);   // >>> [class java.lang.String]

        // Tests for 'set_get' step.

        List<Long> res4 = jedis.jsonStrLen("bike", new Path2("$"));
        System.out.println(res4);   // >>> [8]

        List<Long> res5 = jedis.jsonStrAppend("bike", new Path2("$"), " (Enduro bikes)");
        System.out.println(res5);   // >>> [23]

        Object res6 = jedis.jsonGet("bike", new Path2("$"));
        System.out.println(res6);   // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        String res7 = jedis.jsonSet("crashes", new Path2("$"), 0);
        System.out.println(res7);   // >>> OK

        Object res8 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1);
        System.out.println(res8);   // >>> [1]

        Object res9 = jedis.jsonNumIncrBy("crashes", new Path2("$"), 1.5);
        System.out.println(res9);   // >>> [2.5]

        Object res10 = jedis.jsonNumIncrBy("crashes", new Path2("$"), -0.75);
        System.out.println(res10);   // >>> [1.75]

        // Tests for 'num' step.

        String res11 = jedis.jsonSet("newbike", new Path2("$"),
            new JSONArray()
                .put("Deimos")
                .put(new JSONObject().put("crashes", 0))
                .put((Object) null)
        );
        System.out.println(res11);  // >>> OK
        
        Object res12 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res12);  // >>> [["Deimos",{"crashes":0},null]]

        Object res13 = jedis.jsonGet("newbike", new Path2("$[1].crashes"));
        System.out.println(res13);  // >>> [0]

        long res14 = jedis.jsonDel("newbike", new Path2("$.[-1]"));
        System.out.println(res14);  // >>> 1

        Object res15 = jedis.jsonGet("newbike", new Path2("$"));
        System.out.println(res15);  // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        String res16 = jedis.jsonSet("riders", new Path2("$"), new JSONArray());
        System.out.println(res16);  // >>> OK

        List<Long> res17 = jedis.jsonArrAppendWithEscape("riders", new Path2("$"), "Norem");
        System.out.println(res17);  // >>> [1]

        Object res18 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res18);  // >>> [["Norem"]]

        List<Long> res19 = jedis.jsonArrInsertWithEscape(
            "riders", new Path2("$"), 1, "Prickett", "Royce", "Castilla"
        );
        System.out.println(res19);  // >>> [4]

        Object res20 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res20);
        // >>> [["Norem","Prickett","Royce","Castilla"]]
        
        List<Long> res21 = jedis.jsonArrTrim("riders", new Path2("$"), 1, 1);
        System.out.println(res21);  // >>> [1]

        Object res22 = jedis.jsonGet("riders", new Path2("$"));
        System.out.println(res22);  // >>> [["Prickett"]]

        Object res23 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res23);  // >>> [Prickett]

        Object res24 = jedis.jsonArrPop("riders", new Path2("$"));
        System.out.println(res24);  // >>> [null]

        // Tests for 'arr2' step.

        String res25 = jedis.jsonSet("bike:1", new Path2("$"),
            new JSONObject()
                .put("model", "Deimos")
                .put("brand", "Ergonom")
                .put("price", 4972)
        );
        System.out.println(res25);  // >>> OK

        List<Long> res26 = jedis.jsonObjLen("bike:1", new Path2("$"));
        System.out.println(res26);  // >>> [3]

        List<List<String>> res27 = jedis.jsonObjKeys("bike:1", new Path2("$"));
        System.out.println(res27);  // >>> [[price, model, brand]]

        // Tests for 'obj' step.

        String inventory_json = "{"
        + "    \"inventory\": {"
        + "        \"mountain_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:1\","
        + "                \"model\": \"Phoebe\","
        + "                \"description\": \"This is a mid-travel trail slayer that is a "
        + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
        + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
        + "and a rack too.  This is the bike for the rider who wants trail manners with "
        + "low fuss ownership.\","
        + "                \"price\": 1920,"
        + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:2\","
        + "                \"model\": \"Quaoar\","
        + "                \"description\": \"Redesigned for the 2020 model year, this "
        + "bike impressed our testers and is the best all-around trail bike we've ever "
        + "tested. The Shimano gear system effectively does away with an external cassette, "
        + "so is super low maintenance in terms of wear and tear. All in all it's an "
        + "impressive package for the price, making it very competitive.\","
        + "                \"price\": 2072,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
        + "                \"colors\": [\"black\", \"white\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:3\","
        + "                \"model\": \"Weywot\","
        + "                \"description\": \"This bike gives kids aged six years and older "
        + "a durable and uberlight mountain bike for their first experience on tracks and easy "
        + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
        + "provide ample stopping ability. If you're after a budget option, this is one of the "
        + "best bikes you could get.\","
        + "                \"price\": 3264,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}"
        + "            }"
        + "        ],"
        + "        \"commuter_bikes\": ["
        + "            {"
        + "                \"id\": \"bike:4\","
        + "                \"model\": \"Salacia\","
        + "                \"description\": \"This bike is a great option for anyone who just "
        + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
        + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
        + "It\u2019s for the rider who wants both efficiency and capability.\","
        + "                \"price\": 1475,"
        + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
        + "                \"colors\": [\"black\", \"silver\"]"
        + "            },"
        + "            {"
        + "                \"id\": \"bike:5\","
        + "                \"model\": \"Mimas\","
        + "                \"description\": \"A real joy to ride, this bike got very high scores "
        + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
        + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
        + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
        + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
        + "throttle. Put it all together and you get a bike that helps redefine what can be "
        + "done for this price.\","
        + "                \"price\": 3941,"
        + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}"
        + "            }"
        + "        ]"
        + "    }"
        + "}";

        String res28 = jedis.jsonSet("bikes:inventory", new Path2("$"), inventory_json);
        System.out.println(res28);  // >>> OK

        // Tests for 'set_bikes' step.

        Object res29 = jedis.jsonGet("bikes:inventory", new Path2("$.inventory.*"));
        System.out.println(res29);
        // >>> [[{"specs":{"material":"carbon","weight":13.1},"price":1920, ...

        // Tests for 'get_bikes' step.

        Object res30 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[*].model")
        );
        System.out.println(res30);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res31 = jedis.jsonGet(
            "bikes:inventory", new Path2("$.inventory[\"mountain_bikes\"][*].model")
        );
        System.out.println(res31);  // >>> ["Phoebe","Quaoar","Weywot"]

        Object res32 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[*].model")
        );
        System.out.println(res32);  // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        Object res33 = jedis.jsonGet("bikes:inventory", new Path2("$..model"));
        System.out.println(res33);
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        Object res34 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..mountain_bikes[0:2].model")
        );
        System.out.println(res34);  // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        Object res35 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]")
        );
        System.out.println(res35);
        // >>> [{"specs":{"material":"aluminium","weight":7.9},"price":2072,...

        // Tests for 'filter1' step.

        Object res36 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material == 'alloy')].model")
        );
        System.out.println(res36);  // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        Object res37 = jedis.jsonGet(
            "bikes:inventory", new Path2("$..[?(@.specs.material =~ '(?i)al')].model")
        );
        System.out.println(res37);
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[0].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[1].regex_pat"),
            "\"(?i)al\""
        );
        jedis.jsonSet(
            "bikes:inventory", new Path2("$.inventory.mountain_bikes[2].regex_pat"),
            "\"(?i)al\""
        );
        
        Object res38 = jedis.jsonGet(
            "bikes:inventory",
            new Path2("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model")
        );
        System.out.println(res38);  // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        Object res39 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res39);
        // >>> [1920,2072,3264,1475,3941]

        Object res40 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), -100);
        System.out.println(res40);  // >>> [1820,1972,3164,1375,3841]

        Object res41 = jedis.jsonNumIncrBy("bikes:inventory", new Path2("$..price"), 100);
        System.out.println(res41);  // >>> [1920,2072,3264,1475,3941]

        // Tests for 'update_bikes' step.

        jedis.jsonSet("bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].price"), 1500);
        Object res42 = jedis.jsonGet("bikes:inventory", new Path2("$..price"));
        System.out.println(res42);  // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        List<Long> res43 = jedis.jsonArrAppendWithEscape(
            "bikes:inventory", new Path2("$.inventory.*[?(@.price<2000)].colors"),
            "\"pink\""
        );
        System.out.println(res43);  // >>> [3, 3]

        Object res44 = jedis.jsonGet("bikes:inventory", new Path2("$..[*].colors"));
        System.out.println(res44);
        // >>> [["black","silver","\"pink\""],["black","white"],["black","silver","\"pink\""]]

        // Tests for 'update_filters2' step.

        jedis.close();
    }
}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.util.concurrent.CompletableFuture;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisAsyncCommands<String, String> asyncCommands = connection.async();

            JsonParser parser = asyncCommands.getJsonParser();

            CompletableFuture<Void> setget = asyncCommands
                    .jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\"")).thenCompose(res1 -> {
                        System.out.println(res1); // OK

                        return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
                    }).thenCompose(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]

                        return asyncCommands.jsonType("bike", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> [STRING]
                    .toCompletableFuture();
            setget.join();

            CompletableFuture<Void> str = asyncCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).thenCompose(res3 -> {
                System.out.println(res3); // >>> [8]

                return asyncCommands.jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\""));
            }).thenCompose(res4 -> {
                System.out.println(res4); // >>> [23]

                return asyncCommands.jsonGet("bike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [["Hyperion (Enduro bikes)"]]
                    .toCompletableFuture();
            str.join();

            CompletableFuture<Void> num = asyncCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .thenCompose(res5 -> {
                        System.out.println(res5); // >>> OK

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1);
                    }).thenCompose(res6 -> {
                        System.out.println(res6); // >>> [1]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5);
                    }).thenCompose(res7 -> {
                        System.out.println(res7); // >>> [2.5]

                        return asyncCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75);
                    })
                    .thenAccept(System.out::println) // >>> [1.75]
                    .toCompletableFuture();
            num.join();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            CompletableFuture<Void> arr = asyncCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            }).thenCompose(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]

                return asyncCommands.jsonGet("newbike", JsonPath.of("$[1].crashes"));
            }).thenCompose(res9 -> {
                System.out.println(res9); // >>> [[0]]

                return asyncCommands.jsonDel("newbike", JsonPath.of("$.[-1]"));
            }).thenCompose(res10 -> {
                System.out.println(res10); // >>> 1

                return asyncCommands.jsonGet("newbike", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .toCompletableFuture();
            arr.join();

            CompletableFuture<Void> arr2 = asyncCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray())
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0,
                                parser.createJsonValue("\"Norem\""));
                    }).thenCompose(res11 -> {
                        System.out.println(res11); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    })

                    .thenCompose(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]

                        return asyncCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 1,
                                parser.createJsonValue("\"Prickett\""), parser.createJsonValue("\"Royce\""),
                                parser.createJsonValue("\"Castilla\""));
                    }).thenCompose(res13 -> {
                        System.out.println(res13); // >>> [4]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res14 -> {
                        System.out.println(res14); // >>> ["Norem","Prickett","Royce","Castilla"]
                        //
                        return asyncCommands.jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1));
                    }).thenCompose(res15 -> {
                        System.out.println(res15); // >>> [1]

                        return asyncCommands.jsonGet("riders", JsonPath.ROOT_PATH);
                    }).thenCompose(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0);
                    }).thenCompose(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                        return asyncCommands.jsonArrpop("riders", JsonPath.ROOT_PATH);
                    })
                    .thenAccept(System.out::println)
                    // >>> null
                    .toCompletableFuture();
            arr2.join();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            CompletableFuture<Void> obj = asyncCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).thenCompose(r -> {
                System.out.println(r); // >>> OK

                return asyncCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH);
            }).thenCompose(res18 -> {
                System.out.println(res18); // >>> [3]

                return asyncCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH);
            })
                    .thenAccept(System.out::println)
                    // >>> [model, brand, price]
                    .toCompletableFuture();
            obj.join();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            CompletableFuture<Void> setBikes = asyncCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .thenAccept(System.out::println) // >>> OK
                    .toCompletableFuture();
            setBikes.join();

            CompletableFuture<Void> getBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*"))
                    .thenAccept(System.out::println)
                    // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .toCompletableFuture();
            getBikes.join();

            CompletableFuture<Void> getMtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).thenCompose(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory[\"mountain_bikes\"][*].model"));
                    }).thenCompose(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot"]]
                    .toCompletableFuture();
            getMtnBikes.join();

            CompletableFuture<Void> getModels = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            getModels.join();

            CompletableFuture<Void> get2MtnBikes = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Phoebe","Quaoar"]]
                    .toCompletableFuture();
            get2MtnBikes.join();

            CompletableFuture<Void> filter1 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .thenAccept(System.out::println)
                    // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .toCompletableFuture();
            filter1.join();

            CompletableFuture<Void> filter2 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Weywot","Mimas"]]
                    .toCompletableFuture();
            filter2.join();

            CompletableFuture<Void> filter3 = asyncCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model"))
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .toCompletableFuture();
            filter3.join();

            CompletableFuture<Void> filter4 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonSet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"),
                                parser.createJsonValue("\"(?i)al\""));
                    }).thenCompose(res22 -> {
                        System.out.println(res22); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory",
                                JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [["Quaoar","Weywot"]]
                    .toCompletableFuture();
            filter4.join();

            CompletableFuture<Void> updateBikes = asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"))
                    .thenCompose(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100);
                    }).thenCompose(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]

                        return asyncCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100);
                    })
                    .thenAccept(System.out::println)
                    // >>> [1920, 2072, 3264, 1475, 3941]
                    .toCompletableFuture();
            updateBikes.join();

            CompletableFuture<Void> updateFilters1 = asyncCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).thenCompose(r -> {
                        System.out.println(r); // >>> OK

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..price"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[1500,2072,3264,1500,3941]]
                    .toCompletableFuture();
            updateFilters1.join();

            CompletableFuture<Void> updateFilters2 = asyncCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).thenCompose(r -> {
                        System.out.println(r); // >>> [3, 3]

                        return asyncCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors"));
                    })
                    .thenAccept(System.out::println)
                    // >>> [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .toCompletableFuture();
            updateFilters2.join();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```java
import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.json.JsonPath;
import io.lettuce.core.json.JsonParser;
import io.lettuce.core.json.JsonArray;
import io.lettuce.core.json.JsonObject;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.json.arguments.JsonRangeArgs;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import reactor.core.publisher.Mono;

public class JsonExample {

    public void run() {
        RedisClient redisClient = RedisClient.create("redis://localhost:6379");

        try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
            RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

            JsonParser parser = reactiveCommands.getJsonParser();

            Mono<Void> setget = reactiveCommands.jsonSet("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\"Hyperion\""))
                    .doOnNext(res1 -> {
                        System.out.println(res1); // OK
                    }).flatMap(res1 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList()).doOnNext(res2 -> {
                        System.out.println(res2); // >>> [["Hyperion"]]
                    }).flatMap(res2 -> reactiveCommands.jsonType("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [STRING]
                    .then();

            Mono<Void> str = reactiveCommands.jsonStrlen("bike", JsonPath.ROOT_PATH).collectList().doOnNext(res3 -> {
                System.out.println(res3); // >>> [8]
            }).flatMap(res3 -> reactiveCommands
                    .jsonStrappend("bike", JsonPath.ROOT_PATH, parser.createJsonValue("\" (Enduro bikes)\"")).collectList())
                    .doOnNext(res4 -> {
                        System.out.println(res4); // >>> [23]
                    }).flatMap(res4 -> reactiveCommands.jsonGet("bike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Hyperion (Enduro bikes)"]]
                    .then();

            Mono<Void> num = reactiveCommands.jsonSet("crashes", JsonPath.ROOT_PATH, parser.createJsonValue("0"))
                    .doOnNext(res5 -> {
                        System.out.println(res5); // >>> OK
                    }).flatMap(res5 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1).collectList())
                    .doOnNext(res6 -> {
                        System.out.println(res6); // >>> [1]
                    }).flatMap(res6 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, 1.5).collectList())
                    .doOnNext(res7 -> {
                        System.out.println(res7); // >>> [2.5]
                    }).flatMap(res7 -> reactiveCommands.jsonNumincrby("crashes", JsonPath.ROOT_PATH, -0.75).collectList())
                    .doOnNext(System.out::println) // >>> [1.75]
                    .then();

            JsonObject crashDetails = parser.createJsonObject();
            crashDetails.put("crashes", parser.createJsonValue("0"));

            JsonArray bikeDetails = parser.createJsonArray();
            bikeDetails.add(parser.createJsonValue("\"Deimos\""));
            bikeDetails.add(crashDetails);
            bikeDetails.add(null);

            Mono<Void> arr = reactiveCommands.jsonSet("newbike", JsonPath.ROOT_PATH, bikeDetails).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList()).doOnNext(res8 -> {
                System.out.println(res8);
                // >>> [["Deimos",{"crashes":0},null]]
            }).flatMap(res8 -> reactiveCommands.jsonGet("newbike", JsonPath.of("$[1].crashes")).collectList())
                    .doOnNext(res9 -> {
                        System.out.println(res9); // >>> [[0]]
                    }).flatMap(res9 -> reactiveCommands.jsonDel("newbike", JsonPath.of("$.[-1]"))).doOnNext(res10 -> {
                        System.out.println(res10); // >>> 1
                    }).flatMap(res10 -> reactiveCommands.jsonGet("newbike", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [[[\"Deimos\",{\"crashes\":0}]]]
                    .then();

            Mono<Void> arr2 = reactiveCommands.jsonSet("riders", JsonPath.ROOT_PATH, parser.createJsonArray()).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonArrinsert("riders", JsonPath.ROOT_PATH, 0, parser.createJsonValue("\"Norem\""))
                    .collectList()).doOnNext(res11 -> {
                        System.out.println(res11); // >>> [1]
                    }).flatMap(res11 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res12 -> {
                        System.out.println(res12); // >>> ["Norem"]
                    })
                    .flatMap(
                            res12 -> reactiveCommands
                                    .jsonArrinsert("riders", JsonPath.ROOT_PATH, 1, parser.createJsonValue("\"Prickett\""),
                                            parser.createJsonValue("\"Royce\""), parser.createJsonValue("\"Castilla\""))
                                    .collectList())
                    .doOnNext(res13 -> {
                        System.out.println(res13); // >>> [4]
                    }).flatMap(res13 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [["Norem","Prickett","Royce","Castilla"]]
                    .flatMap(res14 -> reactiveCommands
                            .jsonArrtrim("riders", JsonPath.ROOT_PATH, new JsonRangeArgs().start(1).stop(1)).collectList())
                    .doOnNext(res15 -> {
                        System.out.println(res15); // >>> [1]
                    }).flatMap(res15 -> reactiveCommands.jsonGet("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(res16 -> {
                        System.out.println(res16); // >>> [[["Prickett"]]]
                    }).flatMap(res16 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH, 0).collectList())
                    .doOnNext(res17 -> {
                        System.out.println(res17); // >>> ["Prickett"]
                    }).flatMap(res17 -> reactiveCommands.jsonArrpop("riders", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> null
                    .then();

            JsonObject bikeObj = parser.createJsonObject().put("model", parser.createJsonValue("\"Deimos\""))
                    .put("brand", parser.createJsonValue("\"Ergonom\"")).put("price", parser.createJsonValue("\"4972\""));

            Mono<Void> obj = reactiveCommands.jsonSet("bike:1", JsonPath.ROOT_PATH, bikeObj).doOnNext(r -> {
                System.out.println(r); // >>> OK
            }).flatMap(r -> reactiveCommands.jsonObjlen("bike:1", JsonPath.ROOT_PATH).collectList()).doOnNext(res18 -> {
                System.out.println(res18); // >>> [3]
            }).flatMap(res18 -> reactiveCommands.jsonObjkeys("bike:1", JsonPath.ROOT_PATH).collectList())
                    .doOnNext(System.out::println) // >>> [model, brand, price]
                    .then();

            String inventory_json_str = "{" + "    \"inventory\": {" + "        \"mountain_bikes\": [" + "            {"
                    + "                \"id\": \"bike:1\"," + "                \"model\": \"Phoebe\","
                    + "                \"description\": \"This is a mid-travel trail slayer that is a "
                    + "fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset "
                    + "gives plenty of gear range to tackle hills and there\u2019s room for mudguards "
                    + "and a rack too.  This is the bike for the rider who wants trail manners with " + "low fuss ownership.\","
                    + "                \"price\": 1920,"
                    + "                \"specs\": {\"material\": \"carbon\", \"weight\": 13.1},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:2\"," + "                \"model\": \"Quaoar\","
                    + "                \"description\": \"Redesigned for the 2020 model year, this "
                    + "bike impressed our testers and is the best all-around trail bike we've ever "
                    + "tested. The Shimano gear system effectively does away with an external cassette, "
                    + "so is super low maintenance in terms of wear and tear. All in all it's an "
                    + "impressive package for the price, making it very competitive.\"," + "                \"price\": 2072,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 7.9},"
                    + "                \"colors\": [\"black\", \"white\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:3\"," + "                \"model\": \"Weywot\","
                    + "                \"description\": \"This bike gives kids aged six years and older "
                    + "a durable and uberlight mountain bike for their first experience on tracks and easy "
                    + "cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes "
                    + "provide ample stopping ability. If you're after a budget option, this is one of the "
                    + "best bikes you could get.\"," + "                \"price\": 3264,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 13.8}" + "            }" + "        ],"
                    + "        \"commuter_bikes\": [" + "            {" + "                \"id\": \"bike:4\","
                    + "                \"model\": \"Salacia\","
                    + "                \"description\": \"This bike is a great option for anyone who just "
                    + "wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, "
                    + "this is a bike which doesn\u2019t break the bank and delivers craved performance.  "
                    + "It\u2019s for the rider who wants both efficiency and capability.\","
                    + "                \"price\": 1475,"
                    + "                \"specs\": {\"material\": \"aluminium\", \"weight\": 16.6},"
                    + "                \"colors\": [\"black\", \"silver\"]" + "            }," + "            {"
                    + "                \"id\": \"bike:5\"," + "                \"model\": \"Mimas\","
                    + "                \"description\": \"A real joy to ride, this bike got very high scores "
                    + "in last years Bike of the year report. The carefully crafted 50-34 tooth chainset "
                    + "and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the "
                    + "high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step "
                    + "frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb "
                    + "throttle. Put it all together and you get a bike that helps redefine what can be "
                    + "done for this price.\"," + "                \"price\": 3941,"
                    + "                \"specs\": {\"material\": \"alloy\", \"weight\": 11.6}" + "            }" + "        ]"
                    + "    }" + "}";

            Charset charset = Charset.forName("UTF-8");
            ByteBuffer inventory_json = charset.encode(inventory_json_str);

            Mono<Void> setBikes = reactiveCommands
                    .jsonSet("bikes:inventory", JsonPath.ROOT_PATH, parser.loadJsonValue(inventory_json))
                    .doOnNext(System.out::println) // >>> OK
                    .then();

            Mono<Void> getBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$.inventory.*")).collectList()
                    .doOnNext(System.out::println) // >>> [[[{"id":"bike:1","model":"Phoebe",...
                    .then();

            Mono<Void> getMtnBikes = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$.inventory.mountain_bikes[*].model")).collectList()
                    .doOnNext(res19 -> {
                        System.out.println(res19); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res19 -> reactiveCommands
                            .jsonGet("bikes:inventory", JsonPath.of("$.inventory[\"mountain_bikes\"][*].model")).collectList())
                    .doOnNext(res20 -> {
                        System.out.println(res20); // >>> [["Phoebe","Quaoar","Weywot"]]
                    })
                    .flatMap(res20 -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[*].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot"]]
                    .then();

            Mono<Void> getModels = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> get2MtnBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[0:2].model"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [["Phoebe","Quaoar"]]
                    .then();

            Mono<Void> filter1 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"))
                    .collectList()
                    .doOnNext(System.out::println) // >>> [[{"id":"bike:2","model":"Quaoar","description":...
                    .then();

            Mono<Void> filter2 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material == 'alloy')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Weywot","Mimas"]]
                    .then();

            Mono<Void> filter3 = reactiveCommands
                    .jsonGet("bikes:inventory", JsonPath.of("$..[?(@.specs.material =~ '(?i)al')].model")).collectList()
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot","Salacia","Mimas"]]
                    .then();

            Mono<Void> filter4 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.mountain_bikes[0].regex_pat"), parser.createJsonValue("\"(?i)al\""))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[1].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    })
                    .flatMap(r -> reactiveCommands.jsonSet("bikes:inventory",
                            JsonPath.of("$.inventory.mountain_bikes[2].regex_pat"), parser.createJsonValue("\"(?i)al\"")))
                    .doOnNext(res22 -> {
                        System.out.println(res22); // >>> OK
                    })
                    .flatMap(res22 -> reactiveCommands
                            .jsonGet("bikes:inventory",
                                    JsonPath.of("$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"))
                            .collectList())
                    .doOnNext(System.out::println) // >>> [["Quaoar","Weywot"]]
                    .then();

            Mono<Void> updateBikes = reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [[1920,2072,3264,1475,3941]]
                    })
                    .flatMap(
                            r -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), -100).collectList())
                    .doOnNext(res23 -> {
                        System.out.println(res23); // >>> [1820, 1972, 3164, 1375, 3841]
                    })
                    .flatMap(res23 -> reactiveCommands.jsonNumincrby("bikes:inventory", JsonPath.of("$..price"), 100)
                            .collectList())
                    .doOnNext(System.out::println) // >>> [1920, 2072, 3264, 1475, 3941]
                    .then();

            Mono<Void> updateFilters1 = reactiveCommands.jsonSet("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].price"), parser.createJsonValue("1500")).doOnNext(r -> {
                        System.out.println(r); // >>> OK
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..price")).collectList())
                    .doOnNext(System.out::println) // >>> [[1500,2072,3264,1500,3941]]
                    .then();

            Mono<Void> updateFilters2 = reactiveCommands.jsonArrappend("bikes:inventory",
                    JsonPath.of("$.inventory.*[?(@.price<2000)].colors"), parser.createJsonValue("\"pink\"")).collectList()
                    .doOnNext(r -> {
                        System.out.println(r); // >>> [3, 3]
                    }).flatMap(r -> reactiveCommands.jsonGet("bikes:inventory", JsonPath.of("$..[*].colors")).collectList())
                    .doOnNext(System.out::println) // >>>
                                                   // [[["black","silver","pink"],["black","white"],["black","silver","pink"]]]
                    .then();

            // Wait for all reactive operations to complete
            Mono.when(setget, str, num, arr, arr2, obj, setBikes, getBikes, getMtnBikes, getModels, get2MtnBikes, filter1,
                    filter2, filter3, filter4, updateBikes, updateFilters1, updateFilters2).block();

        } finally {
            redisClient.shutdown();
        }
    }

}
```

```go
package example_commands_test

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func ExampleClient_setget() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res1, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

	res2, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2) // >>> ["Hyperion"]

	res3, err := rdb.JSONType(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3) // >>> [[string]]

}

func ExampleClient_str() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bike", "$",
		"\"Hyperion\"",
	).Result()

	if err != nil {
		panic(err)
	}

	res4, err := rdb.JSONStrLen(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res4[0]) // >>> 8

	res5, err := rdb.JSONStrAppend(ctx, "bike", "$", "\" (Enduro bikes)\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res5[0]) // >>> 23

	res6, err := rdb.JSONGet(ctx, "bike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Hyperion (Enduro bikes)"]

}

func ExampleClient_num() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res7, err := rdb.JSONSet(ctx, "crashes", "$", 0).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> OK

	res8, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8) // >>> [1]

	res9, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", 1.5).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> [2.5]

	res10, err := rdb.JSONNumIncrBy(ctx, "crashes", "$", -0.75).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> [1.75]

}

func ExampleClient_arr() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res11, err := rdb.JSONSet(ctx, "newbike", "$",
		[]interface{}{
			"Deimos",
			map[string]interface{}{"crashes": 0},
			nil,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> [["Deimos",{"crashes":0},null]]

	res13, err := rdb.JSONGet(ctx, "newbike", "$[1].crashes").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> [0]

	res14, err := rdb.JSONDel(ctx, "newbike", "$.[-1]").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> 1

	res15, err := rdb.JSONGet(ctx, "newbike", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [["Deimos",{"crashes":0}]]

}

func ExampleClient_arr2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res16, err := rdb.JSONSet(ctx, "riders", "$", []interface{}{}).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> OK

	res17, err := rdb.JSONArrAppend(ctx, "riders", "$", "\"Norem\"").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1]

	res18, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> [["Norem"]]

	res19, err := rdb.JSONArrInsert(ctx, "riders", "$", 1,
		"\"Prickett\"", "\"Royce\"", "\"Castilla\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // [3]

	res20, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [["Norem", "Prickett", "Royce", "Castilla"]]

	rangeStop := 1

	res21, err := rdb.JSONArrTrimWithArgs(ctx, "riders", "$",
		&redis.JSONArrTrimArgs{Start: 1, Stop: &rangeStop},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21) // >>> [1]

	res22, err := rdb.JSONGet(ctx, "riders", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res22) // >>> [["Prickett"]]

	res23, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res23) // >>> [["Prickett"]]

	res24, err := rdb.JSONArrPop(ctx, "riders", "$", -1).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res24) // []

}

func ExampleClient_obj() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	res25, err := rdb.JSONSet(ctx, "bike:1", "$",
		map[string]interface{}{
			"model": "Deimos",
			"brand": "Ergonom",
			"price": 4972,
		},
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res25) // >>> OK

	res26, err := rdb.JSONObjLen(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(*res26[0]) // >>> 3

	res27, err := rdb.JSONObjKeys(ctx, "bike:1", "$").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res27) // >>> [brand model price]

}

var inventory_json = map[string]interface{}{
	"inventory": map[string]interface{}{
		"mountain_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:1",
				"model": "Phoebe",
				"description": "This is a mid-travel trail slayer that is a fantastic " +
					"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
					"gives plenty of gear range to tackle hills and there\u2019s room for " +
					"mudguards and a rack too.  This is the bike for the rider who wants " +
					"trail manners with low fuss ownership.",
				"price":  1920,
				"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:2",
				"model": "Quaoar",
				"description": "Redesigned for the 2020 model year, this bike " +
					"impressed our testers and is the best all-around trail bike we've " +
					"ever tested. The Shimano gear system effectively does away with an " +
					"external cassette, so is super low maintenance in terms of wear " +
					"and tear. All in all it's an impressive package for the price, " +
					"making it very competitive.",
				"price":  2072,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
				"colors": []interface{}{"black", "white"},
			},
			map[string]interface{}{
				"id":    "bike:3",
				"model": "Weywot",
				"description": "This bike gives kids aged six years and older " +
					"a durable and uberlight mountain bike for their first experience " +
					"on tracks and easy cruising through forests and fields. A set of " +
					"powerful Shimano hydraulic disc brakes provide ample stopping " +
					"ability. If you're after a budget option, this is one of the best " +
					"bikes you could get.",
				"price": 3264,
				"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
			},
		},
		"commuter_bikes": []interface{}{
			map[string]interface{}{
				"id":    "bike:4",
				"model": "Salacia",
				"description": "This bike is a great option for anyone who just " +
					"wants a bike to get about on With a slick-shifting Claris gears " +
					"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
					"bank and delivers craved performance.  It\u2019s for the rider " +
					"who wants both efficiency and capability.",
				"price":  1475,
				"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
				"colors": []interface{}{"black", "silver"},
			},
			map[string]interface{}{
				"id":    "bike:5",
				"model": "Mimas",
				"description": "A real joy to ride, this bike got very high " +
					"scores in last years Bike of the year report. The carefully " +
					"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
					"easy-on-the-legs bottom gear for climbing, and the high-quality " +
					"Vittoria Zaffiro tires give balance and grip.It includes " +
					"a low-step frame , our memory foam seat, bump-resistant shocks and " +
					"conveniently placed thumb throttle. Put it all together and you " +
					"get a bike that helps redefine what can be done for this price.",
				"price": 3941,
				"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
			},
		},
	},
}

func ExampleClient_setbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	var inventory_json = map[string]interface{}{
		"inventory": map[string]interface{}{
			"mountain_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:1",
					"model": "Phoebe",
					"description": "This is a mid-travel trail slayer that is a fantastic " +
						"daily driver or one bike quiver. The Shimano Claris 8-speed groupset " +
						"gives plenty of gear range to tackle hills and there\u2019s room for " +
						"mudguards and a rack too.  This is the bike for the rider who wants " +
						"trail manners with low fuss ownership.",
					"price":  1920,
					"specs":  map[string]interface{}{"material": "carbon", "weight": 13.1},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:2",
					"model": "Quaoar",
					"description": "Redesigned for the 2020 model year, this bike " +
						"impressed our testers and is the best all-around trail bike we've " +
						"ever tested. The Shimano gear system effectively does away with an " +
						"external cassette, so is super low maintenance in terms of wear " +
						"and tear. All in all it's an impressive package for the price, " +
						"making it very competitive.",
					"price":  2072,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 7.9},
					"colors": []interface{}{"black", "white"},
				},
				map[string]interface{}{
					"id":    "bike:3",
					"model": "Weywot",
					"description": "This bike gives kids aged six years and older " +
						"a durable and uberlight mountain bike for their first experience " +
						"on tracks and easy cruising through forests and fields. A set of " +
						"powerful Shimano hydraulic disc brakes provide ample stopping " +
						"ability. If you're after a budget option, this is one of the best " +
						"bikes you could get.",
					"price": 3264,
					"specs": map[string]interface{}{"material": "alloy", "weight": 13.8},
				},
			},
			"commuter_bikes": []interface{}{
				map[string]interface{}{
					"id":    "bike:4",
					"model": "Salacia",
					"description": "This bike is a great option for anyone who just " +
						"wants a bike to get about on With a slick-shifting Claris gears " +
						"from Shimano\u2019s, this is a bike which doesn\u2019t break the " +
						"bank and delivers craved performance.  It\u2019s for the rider " +
						"who wants both efficiency and capability.",
					"price":  1475,
					"specs":  map[string]interface{}{"material": "aluminium", "weight": 16.6},
					"colors": []interface{}{"black", "silver"},
				},
				map[string]interface{}{
					"id":    "bike:5",
					"model": "Mimas",
					"description": "A real joy to ride, this bike got very high " +
						"scores in last years Bike of the year report. The carefully " +
						"crafted 50-34 tooth chainset and 11-32 tooth cassette give an " +
						"easy-on-the-legs bottom gear for climbing, and the high-quality " +
						"Vittoria Zaffiro tires give balance and grip.It includes " +
						"a low-step frame , our memory foam seat, bump-resistant shocks and " +
						"conveniently placed thumb throttle. Put it all together and you " +
						"get a bike that helps redefine what can be done for this price.",
					"price": 3941,
					"specs": map[string]interface{}{"material": "alloy", "weight": 11.6},
				},
			},
		},
	}

	res1, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res1) // >>> OK

}

func ExampleClient_getbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res2, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$.inventory.*",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res2)
	// >>>
	// [
	//   [
	//     {
	//       "colors": [
	//         "black",
	//         "silver"
	// ...

}

func ExampleClient_getmtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res3, err := rdb.JSONGet(ctx, "bikes:inventory",
		"$.inventory.mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res3)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res4, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$.inventory[\"mountain_bikes\"][*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res4)
	// >>> ["Phoebe","Quaoar","Weywot"]

	res5, err := rdb.JSONGet(ctx,
		"bikes:inventory", "$..mountain_bikes[*].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res5)
	// >>> ["Phoebe","Quaoar","Weywot"]

}

func ExampleClient_getmodels() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res6, err := rdb.JSONGet(ctx, "bikes:inventory", "$..model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res6) // >>> ["Salacia","Mimas","Phoebe","Quaoar","Weywot"]

}

func ExampleClient_get2mtnbikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res7, err := rdb.JSONGet(ctx, "bikes:inventory", "$..mountain_bikes[0:2].model").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res7) // >>> ["Phoebe","Quaoar"]

}

func ExampleClient_filter1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res8, err := rdb.JSONGetWithArgs(ctx, "bikes:inventory",
		&redis.JSONGetArgs{Indent: "  ", Newline: "\n", Space: " "},
		"$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res8)
	// >>>
	// [
	//   {
	//     "colors": [
	//       "black",
	//       "white"
	//     ],
	//     "description": "Redesigned for the 2020 model year
	// ...

}

func ExampleClient_filter2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res9, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material == 'alloy')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res9) // >>> ["Mimas","Weywot"]

}

func ExampleClient_filter3() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res10, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$..[?(@.specs.material =~ '(?i)al')].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res10) // >>> ["Salacia","Mimas","Quaoar","Weywot"]

}

func ExampleClient_filter4() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res11, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[0].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res11) // >>> OK

	res12, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[1].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res12) // >>> OK

	res13, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[2].regex_pat",
		"\"(?i)al\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res13) // >>> OK

	res14, err := rdb.JSONGet(ctx,
		"bikes:inventory",
		"$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res14) // >>> ["Quaoar","Weywot"]

}

func ExampleClient_updatebikes() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res15, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res15) // >>> [1475,3941,1920,2072,3264]

	res16, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", -100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res16) // >>> [1375,3841,1820,1972,3164]

	res17, err := rdb.JSONNumIncrBy(ctx, "bikes:inventory", "$..price", 100).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res17) // >>> [1475,3941,1920,2072,3264]

}

func ExampleClient_updatefilters1() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res18, err := rdb.JSONSet(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].price",
		1500,
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res18) // >>> OK

	res19, err := rdb.JSONGet(ctx, "bikes:inventory", "$..price").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res19) // >>> [1500,3941,1500,2072,3264]

}

func ExampleClient_updatefilters2() {
	ctx := context.Background()

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password docs
		DB:       0,  // use default DB
	})

	_, err := rdb.JSONSet(ctx, "bikes:inventory", "$", inventory_json).Result()

	if err != nil {
		panic(err)
	}

	res20, err := rdb.JSONArrAppend(ctx,
		"bikes:inventory",
		"$.inventory.*[?(@.price<2000)].colors",
		"\"pink\"",
	).Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res20) // >>> [3 3]

	res21, err := rdb.JSONGet(ctx, "bikes:inventory", "$..[*].colors").Result()

	if err != nil {
		panic(err)
	}

	fmt.Println(res21)
	// >>> [["black","silver","pink"],["black","silver","pink"],["black","white"]]

}
```

```c#

using NRedisStack;
using NRedisStack.RedisStackCommands;
using NRedisStack.Tests;
using StackExchange.Redis;

public class JsonTutorial
{
    public void Run()
    {
        var muxer = ConnectionMultiplexer.Connect("localhost:6379");
        var db = muxer.GetDatabase();

        bool res1 = db.JSON().Set("bike", "$", "\"Hyperion\"");
        Console.WriteLine(res1);    // >>> True

        RedisResult res2 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res2);    // >>> ["Hyperion"]

        JsonType[] res3 = db.JSON().Type("bike", "$");
        Console.WriteLine(string.Join(", ", res3)); // >>> STRING

        // Tests for 'set_get' step.

        long?[] res4 = db.JSON().StrLen("bike", "$");
        Console.Write(string.Join(", ", res4)); // >>> 8

        long?[] res5 = db.JSON().StrAppend("bike", " (Enduro bikes)");
        Console.WriteLine(string.Join(", ", res5)); // >>> 23

        RedisResult res6 = db.JSON().Get("bike", path: "$");
        Console.WriteLine(res6);    // >>> ["Hyperion (Enduro bikes)"]

        // Tests for 'str' step.

        bool res7 = db.JSON().Set("crashes", "$", 0);
        Console.WriteLine(res7);    // >>> True

        double?[] res8 = db.JSON().NumIncrby("crashes", "$", 1);
        Console.WriteLine(string.Join(", ", res8));    // >>> 1

        double?[] res9 = db.JSON().NumIncrby("crashes", "$", 1.5);
        Console.WriteLine(string.Join(", ", res9));    // >>> 2.5

        double?[] res10 = db.JSON().NumIncrby("crashes", "$", -0.75);
        Console.WriteLine(string.Join(", ", res10));    // >>> 1.75

        // Tests for 'num' step.

        bool res11 = db.JSON().Set("newbike", "$", new object?[] { "Deimos", new { crashes = 0 }, null });
        Console.WriteLine(res11);   // >>> True

        RedisResult res12 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res12);   //  >>> [["Deimos",{"crashes":0},null]]

        RedisResult res13 = db.JSON().Get("newbike", path: "$[1].crashes");
        Console.WriteLine(res13);   // >>> [0]

        long res14 = db.JSON().Del("newbike", "$.[-1]");
        Console.WriteLine(res14);   // >>> 1

        RedisResult res15 = db.JSON().Get("newbike", path: "$");
        Console.WriteLine(res15);   // >>> [["Deimos",{"crashes":0}]]

        // Tests for 'arr' step.

        bool res16 = db.JSON().Set("riders", "$", new object[] { });
        Console.WriteLine(res16);   // >>> True

        long?[] res17 = db.JSON().ArrAppend("riders", "$", "Norem");
        Console.WriteLine(string.Join(", ", res17));    // >>> 1

        RedisResult res18 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res18);   // >>> [["Norem"]]

        long?[] res19 = db.JSON().ArrInsert("riders", "$", 1, "Prickett", "Royce", "Castilla");
        Console.WriteLine(string.Join(", ", res19));    // >>> 4

        RedisResult res20 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res20);   // >>> [["Norem","Prickett","Royce","Castilla"]]

        long?[] res21 = db.JSON().ArrTrim("riders", "$", 1, 1);
        Console.WriteLine(string.Join(", ", res21));    // 1

        RedisResult res22 = db.JSON().Get("riders", path: "$");
        Console.WriteLine(res22);   // >>> [["Prickett"]]

        RedisResult[] res23 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res23)); // >>> "Prickett"

        RedisResult[] res24 = db.JSON().ArrPop("riders", "$");
        Console.WriteLine(string.Join(", ", (object[])res24)); // >>> <Empty string>

        // Tests for 'arr2' step.

        bool res25 = db.JSON().Set("bike:1", "$",
            new { model = "Deimos", brand = "Ergonom", price = 4972 }
        );
        Console.WriteLine(res25);   // >>> True

        long?[] res26 = db.JSON().ObjLen("bike:1", "$");
        Console.WriteLine(string.Join(", ", res26));    // >>> 3

        IEnumerable<HashSet<string>> res27 = db.JSON().ObjKeys("bike:1", "$");
        Console.WriteLine(
            string.Join(", ", res27.Select(b => $"{string.Join(", ", b.Select(c => $"{c}"))}"))
        ); // >>> model, brand, price

        // Tests for 'obj' step.

        string inventoryJson = @"
{
    ""inventory"": {
        ""mountain_bikes"": [
            {
                ""id"": ""bike:1"",
                ""model"": ""Phoebe"",
                ""description"": ""This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership."",
                ""price"": 1920,
                ""specs"": {""material"": ""carbon"", ""weight"": 13.1},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:2"",
                ""model"": ""Quaoar"",
                ""description"": ""Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive."",
                ""price"": 2072,
                ""specs"": {""material"": ""aluminium"", ""weight"": 7.9},
                ""colors"": [""black"", ""white""]
            },
            {
                ""id"": ""bike:3"",
                ""model"": ""Weywot"",
                ""description"": ""This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get."",
                ""price"": 3264,
                ""specs"": {""material"": ""alloy"", ""weight"": 13.8}
            }
        ],
        ""commuter_bikes"": [
            {
                ""id"": ""bike:4"",
                ""model"": ""Salacia"",
                ""description"": ""This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.  It\u2019s for the rider who wants both efficiency and capability."",
                ""price"": 1475,
                ""specs"": {""material"": ""aluminium"", ""weight"": 16.6},
                ""colors"": [""black"", ""silver""]
            },
            {
                ""id"": ""bike:5"",
                ""model"": ""Mimas"",
                ""description"": ""A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price."",
                ""price"": 3941,
                ""specs"": {""material"": ""alloy"", ""weight"": 11.6}
            }
        ]
    }
}";

        bool res28 = db.JSON().Set("bikes:inventory", "$", inventoryJson);
        Console.WriteLine(res28);   // >>> True

        // Tests for 'set_bikes' step.

        RedisResult res29 = db.JSON().Get("bikes:inventory", path: "$.inventory.*");
        Console.WriteLine(res29);   // >>> {[[{"id":"bike:1","model":"Phoebe", ...

        // Tests for 'get_bikes' step.

        RedisResult res30 = db.JSON().Get("bikes:inventory", path: "$.inventory.mountain_bikes[*].model");
        Console.WriteLine(res30);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res31 = db.JSON().Get("bikes:inventory", path: "$.inventory[\"mountain_bikes\"][*].model");
        Console.WriteLine(res31);   // >>> ["Phoebe","Quaoar","Weywot"]

        RedisResult res32 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[*].model");
        Console.WriteLine(res32);   // >>> ["Phoebe","Quaoar","Weywot"]

        // Tests for 'get_mtnbikes' step.

        RedisResult res33 = db.JSON().Get("bikes:inventory", path: "$..model");
        Console.WriteLine(res33);   // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'get_models' step.

        RedisResult res34 = db.JSON().Get("bikes:inventory", path: "$..mountain_bikes[0:2].model");
        Console.WriteLine(res34);   // >>> ["Phoebe","Quaoar"]

        // Tests for 'get2mtnbikes' step.

        RedisResult res35 = db.JSON().Get(
            "bikes:inventory",
            path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]"
        );
        Console.WriteLine(res35);
        // >>> [{"id":"bike:2","model":"Quaoar","description":"Redesigned for the 2020 model year...

        // Tests for 'filter1' step.

        RedisResult res36 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material == 'alloy')].model"
        );
        Console.WriteLine(res36);   // >>> ["Weywot","Mimas"]

        // Tests for 'filter2' step.

        RedisResult res37 = db.JSON().Get(
            "bikes:inventory",
            path: "$..[?(@.specs.material =~ '(?i)al')].model"
        );
        Console.WriteLine(res37);   // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        // Tests for 'filter3' step.

        bool res38 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[0].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res38);   // >>> True

        bool res39 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[1].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res39);   // >>> True

        bool res40 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.mountain_bikes[2].regex_pat",
            "\"(?i)al\""
        );
        Console.WriteLine(res40);   // >>> True

        RedisResult res41 = db.JSON().Get(
            "bikes:inventory",
            path: "$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model"
        );
        Console.WriteLine(res41);   // >>> ["Quaoar","Weywot"]

        // Tests for 'filter4' step.

        RedisResult res42 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res42);   // >>> [1920,2072,3264,1475,3941]

        double?[] res43 = db.JSON().NumIncrby("bikes:inventory", "$..price", -100);
        Console.WriteLine(string.Join(", ", res43));    // >>> 1820, 1972, 3164, 1375, 3841

        double?[] res44 = db.JSON().NumIncrby("bikes:inventory", "$..price", 100);
        Console.WriteLine(string.Join(", ", res44));    // >>> 1920, 2072, 3264, 1475, 3941

        // Tests for 'update_bikes' step.

        bool res45 = db.JSON().Set(
            "bikes:inventory",
            "$.inventory.*[?(@.price<2000)].price",
            1500
        );
        Console.WriteLine(res45);   // >>> True

        RedisResult res46 = db.JSON().Get("bikes:inventory", path: "$..price");
        Console.WriteLine(res46);   // >>> [1500,2072,3264,1500,3941]

        // Tests for 'update_filters1' step.

        long?[] res47 = db.JSON().ArrAppend(
            "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink"
        );
        Console.WriteLine(string.Join(", ", res47));    // >>> 3, 3

        RedisResult res48 = db.JSON().Get("bikes:inventory", path: "$..[*].colors");
        Console.WriteLine(res48);   // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]

        // Tests for 'update_filters2' step.

    }
}

```

```php
<?php

require 'vendor/autoload.php';

use Predis\Client as PredisClient;

class DtJsonTest
{
    public function testDtJson() {
        $r = new PredisClient([
            'scheme'   => 'tcp',
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'password' => '',
            'database' => 0,
        ]);

        $res1 = $r->jsonset('bike', '$', '"Hyperion"');
        echo $res1 . PHP_EOL;
        // >>> OK

        $res2 = $r->jsonget('bike', '', '', '', '$');
        echo $res2 . PHP_EOL;
        // >>> ["Hyperion"]

        $res3 = $r->jsontype('bike', '$');
        echo json_encode($res3) . PHP_EOL;
        // >>> ["string"]

        $res4 = $r->jsonstrlen('bike', '$');
        echo json_encode($res4) . PHP_EOL;
        // >>> [8]

        $res5 = $r->jsonstrappend('bike', '$', '" (Enduro bikes)"');
        echo json_encode($res5) . PHP_EOL;
        // >>> [23]

        $res6 = $r->jsonget('bike', '', '', '', '$');
        echo $res6 . PHP_EOL;
        // >>> "Hyperion (Enduro bikes)"

        $res7 = $r->jsonset('crashes', '$', '0');
        echo $res7 . PHP_EOL;
        // >>> OK

        $res8 = $r->jsonnumincrby('crashes', '$', 1);
        echo $res8 . PHP_EOL;
        // >>> [1]

        $res9 = $r->jsonnumincrby('crashes', '$', 1.5);
        echo $res9 . PHP_EOL;
        // >>> [2.5]

        $res10 = $r->jsonnumincrby('crashes', '$', -0.75);
        echo $res10 . PHP_EOL;
        // >>> [1.75]

        $newbike = json_encode(["Deimos", ["crashes" => 0], null], JSON_THROW_ON_ERROR);
        $res11 = $r->jsonset('newbike', '$', $newbike);
        echo $res11 . PHP_EOL;
        // >>> OK

        $res12 = $r->jsonget('newbike', '', '', '', '$');
        echo $res12 . PHP_EOL;
        // >>> [["Deimos",{"crashes":0},null]]

        $res13 = $r->jsonget('newbike', '', '', '', '$[1].crashes');
        echo $res13 . PHP_EOL;
        // >>> 0

        $res14 = $r->jsondel('newbike', '$.[-1]');
        echo $res14 . PHP_EOL;
        // >>> 1

        $res15 = $r->jsonget('newbike', '', '', '', '$');
        echo $res15 . PHP_EOL;
        // >>> ["Deimos",{"crashes":0}]

        $res16 = $r->jsonset('riders', '$', '[]');
        echo $res16 . PHP_EOL;
        // >>> OK

        $res17 = $r->jsonarrappend('riders', '$', '"Norem"');
        echo json_encode($res17) . PHP_EOL;
        // >>> [1]

        $res18 = $r->jsonget('riders', '', '', '', '$');
        echo $res18 . PHP_EOL;
        // >>> ["Norem"]

        $res19 = $r->jsonarrinsert('riders', '$', 1, '"Prickett"', '"Royce"', '"Castilla"');
        echo json_encode($res19) . PHP_EOL;
        // >>> [4]

        $res20 = $r->jsonget('riders', '', '', '', '$');
        echo $res20 . PHP_EOL;
        // >>> ["Norem","Prickett","Royce","Castilla"]

        $res21 = $r->jsonarrtrim('riders', '$', 1, 1);
        echo json_encode($res21) . PHP_EOL;
        // >>> [1]

        $res22 = $r->jsonget('riders', '', '', '', '$');
        echo $res22 . PHP_EOL;
        // >>> ["Prickett"]

        $res23 = $r->jsonarrpop('riders', '$');
        echo json_encode($res23) . PHP_EOL;
        // >>> ["\"Prickett\""]

        $res24 = $r->jsonarrpop('riders', '$');
        echo json_encode($res24) . PHP_EOL;
        // >>> [null]

        $bike1 = json_encode([
            'model' => 'Deimos',
            'brand' => 'Ergonom',
            'price' => 4972,
        ], JSON_THROW_ON_ERROR);
        $res25 = $r->jsonset('bike:1', '$', $bike1);
        echo $res25 . PHP_EOL;
        // >>> OK

        $res26 = $r->jsonobjlen('bike:1', '$');
        echo json_encode($res26) . PHP_EOL;
        // >>> [3]

        $res27 = $r->jsonobjkeys('bike:1', '$');
        echo json_encode($res27) . PHP_EOL;
        // >>> [["model","brand","price"]]

        $inventory = [
            'inventory' => [
                'mountain_bikes' => [
                    [
                        'id' => 'bike:1',
                        'model' => 'Phoebe',
                        'description' => 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too.  This is the bike for the rider who wants trail manners with low fuss ownership.',
                        'price' => 1920,
                        'specs' => ['material' => 'carbon', 'weight' => 13.1],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:2',
                        'model' => 'Quaoar',
                        'description' => "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and tear. All in all it's an impressive package for the price, making it very competitive.",
                        'price' => 2072,
                        'specs' => ['material' => 'aluminium', 'weight' => 7.9],
                        'colors' => ['black', 'white'],
                    ],
                    [
                        'id' => 'bike:3',
                        'model' => 'Weywot',
                        'description' => 'This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you\'re after a budget option, this is one of the best bikes you could get.',
                        'price' => 3264,
                        'specs' => ['material' => 'alloy', 'weight' => 13.8],
                    ],
                ],
                'commuter_bikes' => [
                    [
                        'id' => 'bike:4',
                        'model' => 'Salacia',
                        'description' => 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.  It’s for the rider who wants both efficiency and capability.',
                        'price' => 1475,
                        'specs' => ['material' => 'aluminium', 'weight' => 16.6],
                        'colors' => ['black', 'silver'],
                    ],
                    [
                        'id' => 'bike:5',
                        'model' => 'Mimas',
                        'description' => 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.',
                        'price' => 3941,
                        'specs' => ['material' => 'alloy', 'weight' => 11.6],
                    ],
                ],
            ],
        ];
        $res1b = $r->jsonset('bikes:inventory', '$', json_encode($inventory, JSON_THROW_ON_ERROR));
        echo $res1b . PHP_EOL;
        // >>> OK

        $res2b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.*');
        echo $res2b . PHP_EOL;
        // >>> [{'id': 'bike:1', 'model': 'Phoebe',

        $res3b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory.mountain_bikes[*].model');
        echo $res3b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res4b = $r->jsonget('bikes:inventory', '', '', '', '$.inventory["mountain_bikes"][*].model');
        echo $res4b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res5b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[*].model');
        echo $res5b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot"]

        $res6b = $r->jsonget('bikes:inventory', '', '', '', '$..model');
        echo $res6b . PHP_EOL;
        // >>> ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]

        $res7b = $r->jsonget('bikes:inventory', '', '', '', '$..mountain_bikes[0:2].model');
        echo $res7b . PHP_EOL;
        // >>> ["Phoebe","Quaoar"]

        $res8b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
        );
        echo $res8b . PHP_EOL;
        // >>> [{"id":"bike:2","model":"Quaoar",...}]

        $res9b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material == 'alloy')].model");
        echo $res9b . PHP_EOL;
        // >>> ["Weywot","Mimas"]

        $res10b = $r->jsonget('bikes:inventory', '', '', '', "$..[?(@.specs.material =~ '(?i)al')].model");
        echo $res10b . PHP_EOL;
        // >>> ["Quaoar","Weywot","Salacia","Mimas"]

        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[0].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[1].regex_pat', '"(?i)al"');
        $r->jsonset('bikes:inventory', '$.inventory.mountain_bikes[2].regex_pat', '"(?i)al"');

        $res14b = $r->jsonget(
            'bikes:inventory',
            '',
            '',
            '',
            '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model'
        );
        echo $res14b . PHP_EOL;
        // >>> ["Quaoar","Weywot"]

        $res15b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res15b . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res16b = $r->jsonnumincrby('bikes:inventory', '$..price', -100);
        echo json_encode($res16b) . PHP_EOL;
        // >>> [1820,1972,3164,1375,3841]

        $res17b = $r->jsonnumincrby('bikes:inventory', '$..price', 100);
        echo json_encode($res17b) . PHP_EOL;
        // >>> [1920,2072,3264,1475,3941]

        $res18b = $r->jsonset('bikes:inventory', '$.inventory.*[?(@.price<2000)].price', '1500');
        $res19b = $r->jsonget('bikes:inventory', '', '', '', '$..price');
        echo $res19b . PHP_EOL;
        // >>> [1500,2072,3264,1500,3941]

        $res20b = $r->jsonarrappend('bikes:inventory', '$.inventory.*[?(@.price<2000)].colors', '"pink"');
        echo json_encode($res20b) . PHP_EOL;
        // >>> [3,3]

        $res21b = $r->jsonget('bikes:inventory', '', '', '', '$..[*].colors');
        echo $res21b . PHP_EOL;
        // >>> [["black","silver","pink"],["black","white"],["black","silver","pink"]]
    }
}

```

## Legacy path syntax

RedisJSON v1 had the following path implementation. JSON v2 still supports this legacy path in addition to JSONPath.

Paths always begin at the root of a Redis JSON value. The root is denoted by a period character (`.`). For paths that reference the root's children, it is optional to prefix the path with the root.

Redis JSON supports both dot notation and bracket notation for object key access. The following paths refer to _headphones_, which is a child of _inventory_ under the root:

*   `.inventory.headphones`
*   `inventory["headphones"]`
*   `['inventory']["headphones"]`

To access an array element, enclose its index within a pair of square brackets. The index is 0-based, with 0 being the first element of the array, 1 being the next element, and so on. You can use negative offsets to access elements starting from the end of the array. For example, -1 is the last element in the array, -2 is the second to last element, and so on.

### JSON key names and path compatibility

By definition, a JSON key can be any valid JSON string. Paths, on the other hand, are traditionally based on JavaScript's (and Java's) variable naming conventions.

Although JSON can store objects that contain arbitrary key names, you can only use a legacy path to access these keys if they conform to these naming syntax rules:

1.  Names must begin with a letter, a dollar sign (`$`), or an underscore (`_`) character
2.  Names can contain letters, digits, dollar signs, and underscores
3.  Names are case-sensitive

## Time complexity of path evaluation

The time complexity of searching (navigating to) an element in the path is calculated from:

1.  Child level - every level along the path adds an additional search
2.  Key search - O(N)†, where N is the number of keys in the parent object
3.  Array search - O(1)

This means that the overall time complexity of searching a path is _O(N\*M)_, where N is the depth and M is the number of parent object keys.

† While this is acceptable for objects where N is small, access can be optimized for larger objects.

## On this page
