RedisGraph

Relational databases (SQL) struggle with deep relationships (JOINs). Graph databases are designed for this, but they can be slow and memory-hungry. RedisGraph takes a different approach by using Linear Algebra to solve graph problems.

1. What is RedisGraph?

RedisGraph is a high-performance graph database module. It implements the Property Graph Model:

  • Nodes: Entities (e.g., Person, Movie).
  • Relationships: Connections (e.g., ACTED_IN, KNOWS).
  • Properties: Attributes on both nodes and relationships (e.g., name, year, rating).

The Secret Sauce: Sparse Matrices

Most graph databases use “Adjacency Lists” (pointers). RedisGraph represents the graph as Sparse Matrices.

  • Traversing a graph becomes Matrix Multiplication.
  • This allows it to process millions of relationships in parallel using optimized CPU instructions (SIMD).
graph LR
  subgraph Graph_View
  A((Alice)) -- KNOWS --> B((Bob))
  B -- KNOWS --> C((Charlie))
  A -- KNOWS --> C
  end

  subgraph Matrix_View
  style Matrix_View fill:var(--bg-main),stroke:var(--border-muted),color:var(--fg-default)

  M1[      Alice  Bob  Charlie]
  M2[Alice   0     1      1   ]
  M3[Bob     0     0      1   ]
  M4[Charlie 0     0      0   ]

  M1 --- M2
  M2 --- M3
  M3 --- M4
  end

2. The Cypher Query Language

RedisGraph uses Cypher, the industry-standard language for graphs (originally from Neo4j). It uses “ASCII Art” to describe patterns.

  • (p:Person): A node labeled Person.
  • -[r:FRIEND]->: A relationship labeled FRIEND.
  • MATCH (a)-[:FRIEND]->(b) RETURN b: Find all friends of ‘a’.

3. Java & Go Implementation

import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.graph.ResultSet;
import redis.clients.jedis.graph.Record;

public class RedisGraphExample {
    public static void main(String[] args) {
        JedisPooled client = new JedisPooled("localhost", 6379);

        // 1. Create Data
        // CREATE (:Person {name:'Alice'})-[:FRIEND]->(:Person {name:'Bob'})
        client.graphQuery("social",
            "CREATE (:Person {name:'Alice'})-[:FRIEND]->(:Person {name:'Bob'})");

        // 2. Query Data
        // MATCH (a:Person)-[:FRIEND]->(b:Person) RETURN a.name, b.name
        ResultSet rs = client.graphQuery("social",
            "MATCH (a:Person)-[:FRIEND]->(b:Person) RETURN a.name, b.name");

        // 3. Iterate Results
        while(rs.hasNext()) {
            Record record = rs.next();
            System.out.println(record.getString(0) + " knows " + record.getString(1));
        }
    }
}
package main

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
)

func main() {
    ctx := context.Background()
    rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})

    // 1. Create Data (Using GRAPH.QUERY command)
    query := "CREATE (:Person {name:'Alice'})-[:FRIEND]->(:Person {name:'Bob'})"
    _, err := rdb.Do(ctx, "GRAPH.QUERY", "social", query).Result()
    if err != nil {
        panic(err)
    }

    // 2. Query Data
    match := "MATCH (a:Person)-[:FRIEND]->(b:Person) RETURN a.name, b.name"
    res, _ := rdb.Do(ctx, "GRAPH.QUERY", "social", match).Result()

    // Note: Parsing Graph results in Go raw client is complex.
    // In production, use a dedicated RedisGraph Go client library.
    fmt.Println("Raw Result:", res)
}

4. Interactive: Graph-to-Matrix Visualizer

Add connections between nodes and see how the Adjacency Matrix updates automatically. This is exactly how RedisGraph stores the structure in memory.

Graph View

A
B
C

Adjacency Matrix

A B C
A 0 0 0
B 0 0 0
C 0 0 0

5. Summary

RedisGraph provides a massive performance leap over traditional table-based relational databases for relationship-heavy queries. By using Linear Algebra instead of pointer chasing, it can handle deep graph traversals in real-time.

It is ideal for:

  • Fraud Detection rings
  • Social Network feeds
  • Recommendation Engines
  • Identity & Access Management (IAM) graphs