Work with JSON documents

Learn how to store, read, and update JSON documents with redis-rs.

This example shows how to work with a JSON document from Rust using redis-rs. It uses one bike:1 document to demonstrate a simple workflow: create the document, read nested fields, update part of the document, and append data to an array.

Unlike some of the other client examples in this section, this page focuses on Redis JSON commands directly rather than on Redis Search.

Install

Add serde_json and enable the json feature for redis. If you want to use the async API, also enable a runtime integration such as tokio-comp.

[dependencies]
serde_json = "1"

# Sync API
redis = { version = "1.0.4", features = ["json"] }

# Async API with Tokio
tokio = { version = "1", features = ["full"] }
redis = { version = "1.0.4", features = ["json", "tokio-comp"] }

Import the required crates

The example uses serde_json::json!() to build the document and the JsonCommands or JsonAsyncCommands trait to access Redis JSON commands.

Foundational: Import the Redis JSON traits and serde_json helpers needed to work with JSON documents in Rust
mod tests {
    use redis::{cmd, Commands, JsonCommands};
    use serde_json::json;

    fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client.get_connection().expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r.json_get("bike:1", "$").expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query(&mut r)
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query(&mut r)
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}
mod tests {
    use redis::{cmd, AsyncCommands, JsonAsyncCommands};
    use serde_json::json;

    async fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client
            .get_multiplexed_async_connection()
            .await
            .expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .await
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r
            .json_get("bike:1", "$")
            .await
            .expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .await
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .await
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .await
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .await
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}

Create some JSON data

Create a sample document representing a bike listing. The nested specs and inventory objects and the colors array let you see how JSON paths work with more realistic data than a flat object.

Foundational: Define a nested JSON document with objects and arrays using serde_json::json!
mod tests {
    use redis::{cmd, Commands, JsonCommands};
    use serde_json::json;

    fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client.get_connection().expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r.json_get("bike:1", "$").expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query(&mut r)
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query(&mut r)
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}
mod tests {
    use redis::{cmd, AsyncCommands, JsonAsyncCommands};
    use serde_json::json;

    async fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client
            .get_multiplexed_async_connection()
            .await
            .expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .await
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r
            .json_get("bike:1", "$")
            .await
            .expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .await
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .await
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .await
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .await
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}

Connect to Redis

Connect to your Redis server in the usual way. See Connect to the server for more connection options.

Foundational: Create a Redis client and open a sync or async connection from Rust
mod tests {
    use redis::{cmd, Commands, JsonCommands};
    use serde_json::json;

    fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client.get_connection().expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r.json_get("bike:1", "$").expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query(&mut r)
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query(&mut r)
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}
mod tests {
    use redis::{cmd, AsyncCommands, JsonAsyncCommands};
    use serde_json::json;

    async fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client
            .get_multiplexed_async_connection()
            .await
            .expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .await
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r
            .json_get("bike:1", "$")
            .await
            .expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .await
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .await
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .await
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .await
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}

Store and retrieve the document

Use JSON.SET to store the whole document at the root path $. You can then retrieve the document again with JSON.GET.

Foundational: Store a complete JSON document with JSON.SET and fetch it again with JSON.GET
mod tests {
    use redis::{cmd, Commands, JsonCommands};
    use serde_json::json;

    fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client.get_connection().expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r.json_get("bike:1", "$").expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query(&mut r)
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query(&mut r)
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}
mod tests {
    use redis::{cmd, AsyncCommands, JsonAsyncCommands};
    use serde_json::json;

    async fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client
            .get_multiplexed_async_connection()
            .await
            .expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .await
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r
            .json_get("bike:1", "$")
            .await
            .expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .await
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .await
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .await
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .await
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}

Read nested fields

JSON paths let you retrieve only the parts of the document you need. This is useful when your application only needs a small subset of the data.

Read nested data: Use JSON paths to retrieve selected fields and arrays without fetching the whole document
mod tests {
    use redis::{cmd, Commands, JsonCommands};
    use serde_json::json;

    fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client.get_connection().expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r.json_get("bike:1", "$").expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query(&mut r)
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query(&mut r)
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}
mod tests {
    use redis::{cmd, AsyncCommands, JsonAsyncCommands};
    use serde_json::json;

    async fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client
            .get_multiplexed_async_connection()
            .await
            .expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .await
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r
            .json_get("bike:1", "$")
            .await
            .expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .await
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .await
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .await
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .await
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}

Update part of the document

You can update individual fields without replacing the whole document. The example below changes the stock count and then applies a price change with JSON.NUMINCRBY.

Update nested values: Modify individual fields in place with JSON.SET and JSON.NUMINCRBY
mod tests {
    use redis::{cmd, Commands, JsonCommands};
    use serde_json::json;

    fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client.get_connection().expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r.json_get("bike:1", "$").expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query(&mut r)
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query(&mut r)
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}
mod tests {
    use redis::{cmd, AsyncCommands, JsonAsyncCommands};
    use serde_json::json;

    async fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client
            .get_multiplexed_async_connection()
            .await
            .expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .await
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r
            .json_get("bike:1", "$")
            .await
            .expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .await
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .await
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .await
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .await
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}

Append to an array

You can also update arrays in place. This example adds another color to the bike and then retrieves the updated array.

Update arrays: Append new elements to a JSON array and read back the updated value
mod tests {
    use redis::{cmd, Commands, JsonCommands};
    use serde_json::json;

    fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client.get_connection().expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r.json_get("bike:1", "$").expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query(&mut r)
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query(&mut r)
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}
mod tests {
    use redis::{cmd, AsyncCommands, JsonAsyncCommands};
    use serde_json::json;

    async fn run() {
        let bike = json!({
            "model": "Deimos",
            "brand": "Ergonom",
            "price": 4972,
            "specs": {
                "material": "carbon",
                "weight": 8.7
            },
            "colors": ["black", "silver"],
            "inventory": {
                "in_stock": 12,
                "warehouse": "w1"
            }
        });

        let client =
            redis::Client::open("redis://127.0.0.1").expect("Failed to create Redis client");
        let mut r = client
            .get_multiplexed_async_connection()
            .await
            .expect("Failed to connect to Redis");


        let stored: bool = r
            .json_set("bike:1", "$", &bike)
            .await
            .expect("Failed to run JSON.SET");
        println!("{}", if stored { "OK" } else { "(nil)" }); // >>> OK

        let bike_json: String = r
            .json_get("bike:1", "$")
            .await
            .expect("Failed to run JSON.GET");
        println!("{bike_json}");
        // >>> [{"model":"Deimos","brand":"Ergonom","price":4972,"specs":{"material":"carbon","weight":8.7},"colors":["black","silver"],"inventory":{"in_stock":12,"warehouse":"w1"}}]


        let material: String = r
            .json_get("bike:1", "$.specs.material")
            .await
            .expect("Failed to run JSON.GET");
        println!("{material}"); // >>> ["carbon"]

        let colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to run JSON.GET");
        println!("{colors}"); // >>> [["black","silver"]]

        let stock: String = r
            .json_get("bike:1", "$.inventory.in_stock")
            .await
            .expect("Failed to run JSON.GET");
        println!("{stock}"); // >>> [12]


        let stock_set: bool = r
            .json_set("bike:1", "$.inventory.in_stock", &json!(8))
            .await
            .expect("Failed to update stock");
        println!("{}", if stock_set { "OK" } else { "(nil)" }); // >>> OK

        let new_price: String = cmd("JSON.NUMINCRBY")
            .arg("bike:1")
            .arg("$.price")
            .arg(-500)
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.NUMINCRBY");
        println!("{new_price}"); // >>> [4472]

        let updated_fields: String = r
            .json_get("bike:1", &["$.price", "$.inventory.in_stock"])
            .await
            .expect("Failed to read updated fields");
        println!("{updated_fields}"); // >>> {"$.price":[4472],"$.inventory.in_stock":[8]}


        let _: redis::Value = cmd("JSON.ARRAPPEND")
            .arg("bike:1")
            .arg("$.colors")
            .arg("\"red\"")
            .query_async(&mut r)
            .await
            .expect("Failed to run JSON.ARRAPPEND");

        let updated_colors: String = r
            .json_get("bike:1", "$.colors")
            .await
            .expect("Failed to read updated colors");
        println!("{updated_colors}"); // >>> [["black","silver","red"]]

    }
}

More information

See the following pages to learn more:

RATE THIS PAGE
Back to top ↑