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.
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.
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.
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.
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.
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.
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.
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: