Redis is phasing out RedisGraph. This blog post explains the motivation behind this decision and the implications for existing Redis customers and community members.
End of support is scheduled for January 31, 2025.
RedisGraph enables you to store and query graph data in Redis using the [Cypher Query Language](https://opencypher.org/). In this article, we will discuss the usage of RedisGraph with .NET.
We'll use the NRedisGraph package in this tutorial. To install the package in your project, use dotnet add package NRedisGraph
.
The easiest way to get up and running with RedisGraph locally is to use the RedisGraph docker image:
docker run -p 6379:6379 redis/redis-stack-server:latest
The above command will start an instance of Redis locally with the RedisGraph module loaded, and you will be able to connect to it on localhost:6379
NRedisGraph makes use of the StackExchange.Redis project which is installed along with NRedisGraph
. To create the RedisGraph
object you'll first create a ConnectionMultiplexer
, and pull a reference to an IDatabase
object from it, and then initialize the RedisGraph
with the IDatabase
object:
var muxer = ConnectionMultiplexer.Connect("localhost");
var db = muxer.GetDatabase();
var graph = new RedisGraph(db);
Querying in RedisGraph applies to a wide array of operations, but fundamentally when executing queries with NRedisGraph, all you need to do is execute graph.Query
or graph.QueryAsync
passing in the name of the graph you want to query and the query you want to run. For example, we'll be using the graph pets
for the remainder of this tutorial, pets
is the name of the key the graph will be stored at. Hence any call to graph.Query
or graph.QueryAsync
will first pass in pets
to indicate the graph to work with.
To create a node in RedisGraph, you'll use the Create Operation. Let's start by making 2 Humans, Alice and Bob:
var createBobResult = await graph.QueryAsync("pets", "CREATE(:human{name:'Bob',age:32})");
await graph.QueryAsync("pets", "CREATE(:human{name:'Alice',age:30})");
Running a Query against RedisGraph will result in a ResultSet
. This result will contain some metadata about the result of the query in the Statistics
section and any results generated by the query. In the above case, the only thing returned is the statistics for the query, which you can print out directly from the results object:
Console.WriteLine($"Nodes Created:{createBobResult.Statistics.NodesCreated}");
Console.WriteLine($"Properties Set:{createBobResult.Statistics.PropertiesSet}");
Console.WriteLine($"Labels Created:{createBobResult.Statistics.LabelsAdded}");
Console.WriteLine($"Operation took:{createBobResult.Statistics.QueryInternalExecutionTime}");
You can create nodes with other labels by simply executing another CREATE statement. For example, if we wanted to create a 'pet' named 'Honey' who is a 5-year-old greyhound, we would run:
await graph.QueryAsync("pets", "CREATE(:pet{name:'Honey',age:5,species:'canine',breed:'Greyhound'})");
Like creating nodes, you can also create relationships in RedisGraph using the Query/QueryAsync commands to create relationships between nodes in RedisGraph. For example, to establish the owner relationship between Bob and the Greyhound Honey, you would use the following:
await graph.QueryAsync("pets",
"MATCH(a:human),(p:pet) WHERE(a.name='Bob' and p.name='Honey') CREATE (a)-[:OWNS]->(p)");
Now that we've created a few Nodes and Relationships between nodes, we can query things in the Graph, again using Query
and QueryAsync
. So, for example, if we wanted to find all of Honey's owners, we would issue the following query:
var matches = await graph.QueryAsync("pets", "MATCH(a:human),(p:pet) where (a)-[:OWNS]->(p) and p.name='Honey' return a");
We can then iterate over the resultant matches, which is the same ResultSet
class we were using before, but it will have actual results we can access this time.
foreach (var match in matches)
{
Console.WriteLine(((Node) match.Values.First()).PropertyMap["name"].Value);
}
We can also find all the walkers of Honey by finding all the human's who have a WALKS
relationship with Honey:
matches = await graph.QueryAsync("pets", "MATCH(a:human),(p:pet) where (a)-[:WALKS]->(p) and p.name='Honey' return a");
Then if we wanted to find all of Bob's dogs, we would query the graph and find all the canines who have an OWNS relationship with a human named Bob:
matches = await graph.QueryAsync("pets", "MATCH(a:human),(p:pet) where (a)-[:OWNS]->(p) and p.species='canine' and a.name='Bob' return p");