How to query Graph data in Redis using Rust

RedisGraph is based on a unique approach and architecture that translates Cypher queries to matrix operations executed over a GraphBLAS engine. This new design allows use cases like social graph operation, fraud detection, and real-time recommendation to be executed 10x โ€“ 600x faster than any other graph database. Undoubtedly, it is the fastest graph database that processes complex graph operations in real time, 10x โ€“ 600x faster than any other graph database. It primariy shows how your data is connected through multiple visualization integrations including RedisInsight, Linkurious, and Graphileon.

Below are the primary use cases of RedisGraph:

  • Recommendation: It allows you to rapidly find connections between your customers and the experiences they want by examining the relationships between them.
  • Graph-aided search: It allows you to search for single or multiple words or phrases and execute full-text and linguistic queries in real time over your graph.
  • Identity and access management: It allows you to define complex resources access permissions as a graph and enable rapid real-time verification of these permissions with a single query.

RedisGraph Rust Client#

redisgraph-rs is an idiomatic Rust client for RedisGraph, the graph database by Redis.This crate parses responses from RedisGraph and converts them into ordinary Rust values. It exposes a very flexible API that allows you to retrieve a single value, a single record or multiple records using only one function: Graph::query.

Follow the steps below to get started with RedisGraph with Rust:

Step 1. Run RedisMod Docker container#

docker run -p 6379:6379 --name redislabs/redismod

Step 2. Verify if RedisGraph module is loaded#

info modules
# Modules
module:name=graph,ver=20405,api=1,filters=0,usedby=[],using=[],options=[]

Step 3. Install Rust#

brew install rust

Step 4. Clone the repository#

git clone https://github.com/malte-v/redisgraph-rs

Step 5. Write a rust program#

Copy the below content and save it as "main.rs" under src directory.

use redis::Client;
use redisgraph::{Graph, RedisGraphResult};
fn main() -> RedisGraphResult<()> {
let client = Client::open("redis://127.0.0.1:6379")?;
let mut connection = client.get_connection()?;
let mut graph = Graph::open(connection, "MotoGP".to_string())?;
// Create six nodes (three riders, three teams) and three relationships between them.
graph.mutate("CREATE (:Rider {name: 'Valentino Rossi', birth_year: 1979})-[:rides]->(:Team {name: 'Yamaha'}), \
(:Rider {name:'Dani Pedrosa', birth_year: 1985, height: 1.58})-[:rides]->(:Team {name: 'Honda'}), \
(:Rider {name:'Andrea Dovizioso', birth_year: 1986, height: 1.67})-[:rides]->(:Team {name: 'Ducati'})")?;
// Get the names and birth years of all riders in team Yamaha.
let results: Vec<(String, u32)> = graph.query("MATCH (r:Rider)-[:rides]->(t:Team) WHERE t.name = 'Yamaha' RETURN r.name, r.birth_year")?;
// Since we know just one rider in our graph rides for team Yamaha,
// we can also write this and only get the first record:
let (name, birth_year): (String, u32) = graph.query("MATCH (r:Rider)-[:rides]->(t:Team) WHERE t.name = 'Yamaha' RETURN r.name, r.birth_year")?;
// Let's now get all the data about the riders we have.
// Be aware of that we only know the height of some riders, and therefore we use an `Option`:
let results: Vec<(String, u32, Option<f32>)> = graph.query("MATCH (r:Rider) RETURN r.name, r.birth_year, r.height")?;
// That was just a demo; we don't need this graph anymore. Let's delete it from the database:
//graph.delete()?;
Ok(())

Step 6. Run the current local package#

cargo run

Step 7. Monitor the Graph query#

1633515550.109594 [0 172.17.0.1:55114] "GRAPH.QUERY" "MotoGP" "CREATE (dummy:__DUMMY_LABEL__)" "--compact"
1633515550.111727 [0 172.17.0.1:55114] "GRAPH.QUERY" "MotoGP" "MATCH (dummy:__DUMMY_LABEL__) DELETE dummy" "--compact"
1633515550.114948 [0 172.17.0.1:55114] "GRAPH.QUERY" "MotoGP" "CREATE (:Rider {name: 'Valentino Rossi', birth_year: 1979})-[:rides]->(:Team {name: 'Yamaha'}), (:Rider {name:'Dani Pedrosa', birth_year: 1985, height: 1.58})-[:rides]->(:Team {name: 'Honda'}), (:Rider {name:'Andrea Dovizioso', birth_year: 1986, height: 1.67})-[:rides]->(:Team {name: 'Ducati'})" "--compact"
1633515550.118380 [0 172.17.0.1:55114] "GRAPH.QUERY" "MotoGP" "MATCH (r:Rider)-[:rides]->(t:Team) WHERE t.name = 'Yamaha' RETURN r.name, r.birth_year" "--compact"
1633515550.120766 [0 172.17.0.1:55114] "GRAPH.QUERY" "MotoGP" "MATCH (r:Rider)-[:rides]->(t:Team) WHERE t.name = 'Yamaha' RETURN r.name, r.birth_year" "--compact"
1633515550.122505 [0 172.17.0.1:55114] "GRAPH.QUERY" "MotoGP" "MATCH (r:Rider) RETURN r.name, r.birth_year, r.height" "--compact"
1633515550.124045 [0 172.17.0.1:55114] "GRAPH.DELETE" "MotoGP"

Step 8. Install RedisInsight#

Follow this link to install RedisInsight. For this demo, we will be using RedisInsight Docker container as shown below:

docker run -d -v redisinsight:/db -p 8001:8001 redislabs/redisinsight:latest

Step 8. Accessing RedisInsight#

Next, point your browser to http://localhost:8001.

Step 9. Run the Graph Query#

You can use the limit clause to limit the number of records returned by a query:

GRAPH.QUERY "MotoGP" "MATCH (r:Rider) RETURN r.name, r.birth_year, r.height"

My Image

References#