Getting Started with Neo4j in .NET with Neo4jClient Library

I have been looking into Neo4j, a graph database, for a while and here is what impressed me the most while trying to work with it through the Neo4jClient .NET library.
2015-12-13 19:07
Tugberk Ugurlu


I am really in love with the side project I am working on now. It is broken down to little "micro" applications (a.k.a. microservices), uses multiple data storage technologies and being brought together through Docker. As a result, the entire solution feels very natural, not-restricted and feels so manageable.

One part of this solution requires to answer a question which involves going very deep inside the data hierarchy. To illustrate what I mean, have a look at the below graph:

movies-with-only-agency-employees-2

Here, we have an agency which has acquired some actors. Also, we have some movies which employed some actors. You can model this in various data storage systems in various ways but the question I want to answer is the following: "What are the movies which employed all of its actors from Agency-A?". Even thinking about the query you would write in T-SQL is enough to melt your brain for this one. It doesn’t mean that SQL Server, MySQL, etc. are bad data storage systems. It’s just that this type of questions are not among those data storage systems' strengths.

Enters: Neo4j

Neo4j is an open-source graph database implemented in Java and accessible from software written in other languages using the Cypher query language through a transactional HTTP endpoint (Wikipedia says). In Neo4j, your data set consists of nodes and relationships between these nodes which you can interact with through the Cypher query language. Cypher is a very powerful, declarative, SQL-inspired language for describing patterns in graphs. The biggest thing that stands out when working with Cypher is the relationships. Relationships are first class citizens in Cypher. Consider the following Cypher query which is brought from the movie sample in Neo4j web client:

You can bring up the this movie sample by just running ":play movie graph" from the Neo4j web client and walk through it.

MATCH (tom:Person {name: "Tom Hanks"})-[:ACTED_IN]->(tomHanksMovies) RETURN tom,tomHanksMovies

This will list all Tom Hanks movies. However, when you read it from left to right, you will pretty much understand what it will do anyway. The interesting part here is the ACTED_IN relationship inside the query. You may think at this point that this is not a big deal as it can probably translate the below T-SQL query:

SELECT * FROM Movies m
INNER JOIN MovieActors ma ON ma.MovieId = m.Id
WHERE ma.ActorId = 1;

However, you will start seeing the power as the questions get interesting. For example, let’s find out Tom Hanks’ co-actors from the every movie he acted in (again, from the same sample):

MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors) RETURN coActors.name

It’s just mind-blowingly complicated to retrieve this from a relational database but with Cypher, it is dead easy. You can start to see that it’s all about building up nodes and declaring the relationships to get the answer to your question in Neo4j.

Neo4j in .NET

As Neo4j communicates through HTTP, you can pretty much find a client implementation in every ecosystem and .NET is not an exception. Amazing people from Readify is maintaining Neo4jClient OSS project. It’s extremely easy to use this and the library has a very good documentation. I especially liked the part where they have documented the thread safety concerns of GraphClient. It is the first thing I wanted to find out and there it was.

Going back to my example which I mentioned at the beginning of this post, I tried to handle this through the .NET Client. Let’s walk through what I did.

You can find the below sample under my DotNetSamples GitHub repository.

First, I initiated the GraphClient and made some adjustments:

var client = new GraphClient(new Uri("http://localhost:7474/db/data"), "neo4j", "1234567890")
{
    JsonContractResolver = new CamelCasePropertyNamesContractResolver()
};

client.Connect();

I started with creating the agency.

var agencyA = new Agency { Name = "Agency-A" };
client.Cypher
    .Create("(agency:Agency {agencyA})")
    .WithParam("agencyA", agencyA)
    .ExecuteWithoutResultsAsync()
    .Wait();

Next is to create the actors and ACQUIRED relationship between the agency and some actors (in below case, only the odd numbered actors):

for (int i = 1; i <= 5; i++)
{
    var actor = new Person { Name = $"Actor-{i}" };

    if ((i % 2) == 0)
    {
        client.Cypher
            .Create("(actor:Person {newActor})")
            .WithParam("newActor", actor)
            .ExecuteWithoutResultsAsync()
            .Wait();
    }
    else
    {
        client.Cypher
            .Match("(agency:Agency)")
            .Where((Agency agency) => agency.Name == agencyA.Name)
            .Create("agency-[:ACQUIRED]->(actor:Person {newActor})")
            .WithParam("newActor", actor)
            .ExecuteWithoutResultsAsync()
            .Wait();
    }
}

Then, I have created the movies :

char[] chars = Enumerable.Range('a', 'z' - 'a' + 1).Select(i => (Char)i).ToArray();
for (int i = 0; i < 3; i++)
{
    var movie = new Movie { Name = $"Movie-{chars[i]}" };

    client.Cypher
        .Create("(movie:Movie {newMovie})")
        .WithParam("newMovie", movie)
        .ExecuteWithoutResultsAsync()
        .Wait();
}

Lastly, I have related existing movies and actors through the EMPLOYED relationship.

client.Cypher
    .Match("(movie:Movie)", "(actor1:Person)", "(actor5:Person)")
    .Where((Movie movie) => movie.Name == "Movie-a")
    .AndWhere((Person actor1) => actor1.Name == "Actor-1")
    .AndWhere((Person actor5) => actor5.Name == "Actor-5")
    .Create("(movie)-[:EMPLOYED]->(actor1), (movie)-[:EMPLOYED]->(actor5)")
    .ExecuteWithoutResultsAsync()
    .Wait();

client.Cypher
    .Match("(movie:Movie)", "(actor1:Person)", "(actor3:Person)", "(actor5:Person)")
    .Where((Movie movie) => movie.Name == "Movie-b")
    .AndWhere((Person actor1) => actor1.Name == "Actor-1")
    .AndWhere((Person actor3) => actor3.Name == "Actor-3")
    .AndWhere((Person actor5) => actor5.Name == "Actor-5")
    .Create("(movie)-[:EMPLOYED]->(actor1), (movie)-[:EMPLOYED]->(actor3), (movie)-[:EMPLOYED]->(actor5)")
    .ExecuteWithoutResultsAsync()
    .Wait();

client.Cypher
    .Match("(movie:Movie)", "(actor2:Person)", "(actor5:Person)")
    .Where((Movie movie) => movie.Name == "Movie-c")
    .AndWhere((Person actor2) => actor2.Name == "Actor-2")
    .AndWhere((Person actor5) => actor5.Name == "Actor-5")
    .Create("(movie)-[:EMPLOYED]->(actor2), (movie)-[:EMPLOYED]->(actor5)")
    .ExecuteWithoutResultsAsync()
    .Wait();

When I run this, I now have the data set that I can play with. I have jumped back to web client and ran the below query to retrieve the relations:

MATCH (agency:Agency)-[:ACQUIRED]->(actor:Person)<-[:EMPLOYED]-(movie:Movie)
RETURN agency, actor, movie

One of the greatest features of the web client is that you can view your query result in a graph representation. How cool is that? You can exactly see the smilarity between the below result and the graph I have put together above:

image

Of course, we can run the same above query through the .NET client and grab the results:

var results = client.Cypher
    .Match("(agency:Agency)-[:ACQUIRED]->(actor:Person)<-[:EMPLOYED]-(movie:Movie)")
    .Return((agency, actor, movie) => new
    {
        Agency = agency.As<Agency>(),
        Actor = actor.As<Person>(),
        Movie = movie.As<Movie>()
    }).Results;

Going Beyond

However, how can we answer my "What are the movies which employed all of its actors from Agency-A?" question? As I am very new to Neo4j, I struggled a lot with this. In fact, I was not even sure whether this was possible to do in Neo4J. I asked this as a question in Stackoverflow (as every stuck developer do) and Christophe Willemsen gave an amazing answer which literally blew my mind. I warn you now as the below query is a bit complex and I am still going through it piece by piece to try to understand it but it does the trick:

MATCH (agency:Agency { name:"Agency-A" })-[:ACQUIRED]->(actor:Person)<-[:EMPLOYED]-(movie:Movie)
WITH DISTINCT movie, collect(actor) AS actors
MATCH (movie)-[:EMPLOYED]->(allemployees:Person)
WITH movie, actors, count(allemployees) AS c
WHERE c = size(actors)
RETURN movie.name

The result is as you would expect:

image

Still Dipping My Toes

I am hooked but this doesn’t mean that Neo4j is the solution to my problems. I am still evaluating it by implementing a few features on top of it. There are a few parts which I haven’t been able to answer exactly yet:

  • How does this scale with large data sets?
  • Can I shard the data across servers?
  • Want are the hosted options?
  • What is the story on geo location queries?

However, the architecture I have in my solution allows me to evaluate this type of technologies. At worst case scenario, Neo4j will not work for me but I will be able to replace it with something else (which I doubt that it will be the case).

Resources



Comments

sign in hotmail
by sign in hotmail on Wednesday, Aug 03 2016 07:07:12 +00:00
Looking forward to reading more. Great article . Really looking forward to read more. Really Cool
roblox
by roblox on Monday, Aug 29 2016 09:57:47 +00:00
Thank you for benefiting from time to focus on this kind of, I feel firmly about it and also really like comprehending far more with this particular subject matter.
color switch
by color switch on Monday, Aug 29 2016 09:58:22 +00:00
In case doable, when you get know-how, is it possible to thoughts modernizing your site together with far more details? It’s extremely useful to me
a10
by a10 on Monday, Aug 29 2016 09:58:50 +00:00
Excellent read, Positive site, where did u come up with the information on this posting?
mortal kombat x
by mortal kombat x on Monday, Aug 29 2016 09:59:18 +00:00
I have read a few of the articles on your website now, and I really like your style. Thanks a million and please keep up the effective work
tell me a joke
by tell me a joke on Thursday, Sep 01 2016 08:01:24 +00:00
Kudos ! thanks for sharing such a great information in a gentle manner. More over it is a good Alexa ranked website. Keep it up and all the best !
shareit for pc
by shareit for pc on Thursday, Sep 01 2016 08:03:32 +00:00
Very good
novorapid
by novorapid on Sunday, Sep 04 2016 23:42:49 +00:00
This is so interesting website !
meen kuzhambum mann paanaiyum
by meen kuzhambum mann paanaiyum on Wednesday, Sep 07 2016 09:19:38 +00:00
very interesting
knock knock jokes
by knock knock jokes on Friday, Sep 09 2016 11:10:09 +00:00
super
tiny take screen recorder
by tiny take screen recorder on Saturday, Sep 10 2016 10:16:57 +00:00
super
instagram login
by instagram login on Tuesday, Sep 13 2016 07:38:34 +00:00
Great
wifi hacker
by wifi hacker on Wednesday, Sep 14 2016 09:42:27 +00:00
super
Female Escorts in Jaipur
by Female Escorts in Jaipur on Monday, Sep 19 2016 10:04:06 +00:00
I am very glad to see this blog. Actually I was looking for this type of blog. Its so fantastic useful post.
happy diwali
by happy diwali on Wednesday, Sep 21 2016 08:09:25 +00:00
Very good
hidden wiki
by hidden wiki on Friday, Sep 23 2016 06:29:25 +00:00
Very nice
rangoli images
by rangoli images on Saturday, Sep 24 2016 10:44:05 +00:00
Super sir
jai
by jai on Monday, Sep 26 2016 12:16:25 +00:00
bigg boss 10 contestants
by bigg boss 10 contestants on Monday, Sep 26 2016 21:43:27 +00:00
great post
happy diwali 2016
by happy diwali 2016 on Monday, Sep 26 2016 21:47:21 +00:00
great post
hostgator black friday
by hostgator black friday on Tuesday, Sep 27 2016 02:36:26 +00:00
Thanks Great Post
Godaddy promo code
by Godaddy promo code on Wednesday, Sep 28 2016 11:51:57 +00:00
Such a very useful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article.Thanks for sharing with us.
how to get help in windows 10
by how to get help in windows 10 on Thursday, Sep 29 2016 07:00:25 +00:00
You're very knowledgeable about it, very deep and spacious, Not everyone has an overview and spacious as you, so wonderful, I can share your opinions on its website reviews, hopefully on your next article
how to get help in windows 10
by how to get help in windows 10 on Thursday, Sep 29 2016 07:03:20 +00:00
It is useful when reading these articles, I have a few days to find these things. It too is excellent, very grateful for your profound contribution
nawalg
by nawalg on Thursday, Sep 29 2016 08:38:15 +00:00
dhimmakada
by dhimmakada on Thursday, Sep 29 2016 09:43:46 +00:00
asok
by asok on Friday, Sep 30 2016 12:12:56 +00:00
Halloween Wallpapers
by Halloween Wallpapers on Sunday, Oct 02 2016 14:23:18 +00:00
Nice info you had in the artcile Halloween Wallpapers
Dhanteras Puja Vidhi
by Dhanteras Puja Vidhi on Friday, Oct 07 2016 08:12:13 +00:00
Thanks for sharing this article dhanteras images
Full Movie Download
by Full Movie Download on Friday, Oct 07 2016 13:44:59 +00:00
nice post to download full movies visit our site Full Movie Download
Full Movie Download
by Full Movie Download on Friday, Oct 07 2016 13:46:08 +00:00
nice post to download full movies visit our site Full Movie Download
Theresa Moore
by Theresa Moore on Sunday, Oct 09 2016 10:51:22 +00:00
Get more news from here. If you want to get updated news and latest tips then you must visit this site. Hope this site will help you a lot. Thanks for reading my description. Visit!
Clark Oaiw
by Clark Oaiw on Sunday, Oct 09 2016 10:52:44 +00:00
Get more news from here. If you want to get updated news and latest tips then you must visit this site. Hope this site will help you a lot. Thanks for reading my description. Visit!
Happy Diwali 2016 Diwali Download
by Happy Diwali 2016 Diwali Download on Tuesday, Oct 11 2016 18:04:20 +00:00
Thank yo nice post
Asok
by Asok on Wednesday, Oct 12 2016 10:30:04 +00:00
Shivaay Movie Collection
by Shivaay Movie Collection on Wednesday, Oct 12 2016 18:36:14 +00:00
awesome...
Halloween Costumes ideas
by Halloween Costumes ideas on Friday, Oct 14 2016 06:24:34 +00:00
Diwali Rangoli Designs Happy Diwali 2016 Status Happy Diwali 2016 Sale Happy Diwali 2016 Wishes Happy Diwali Messages Happy Deepawali 2016 Sale Happy Divali 2016 Pics Happy dhanterash images Happy dhanterash Wishes Happy Diwali SMSes Happy Diwali Quotes Happy Diwali Status Happy Diwali Crackers Happy Diwali 2016 Photos Happy Diwali 2016 images Happy Diwali Gifts ideas Happy Diwali 2016 Pictures Happy Diwali 2016 Pictures Wishes quotes on diwali Happy Diwali 2016 Wallpapers deepavali images Hd Happy deepavali 2016 essay Happy gowardhan puja 2016 Happy gowardhan puja 2016 images Happy gowardhan puja 2016 Wishes kalash decoration ideas Happy Karwa Chauth 2016 Happy Karwa Chauth images 2016 Happy Karwa Chauth 2016 Wishes Happy Diwali images Free Download Happy Diwali 2016 Gifts Happy Diwali 2016 Greetings Happy Diwali 2016 Quotes Happy Diwali 2016 Messages Happy Halloween 2016 images Happy Halloween 2016 Pictures Happy Halloween 2016 Photos Happy Halloween 2016 Wallpapers Happy Halloween 2016 Graphics Happy Halloween 2016 Screensavers Happy Halloween wallpapers hd creepy Halloween wallpapers 2016 Happy Halloween wallpapers screensavers Happy Halloween wallpaper download Happy Halloween bilder imagens de Happy Halloween Happy Halloween images with quotes Happy Halloween images free download Happy Halloween Facebook Pictures Happy Halloween 2016 quotes Happy Halloween 2016 wishes Happy Halloween 2016 messages Happy Halloween 2016 sayings happy halloween 2016 greetings Happy Halloween wishes sms Happy Halloween funny quotes sayings Happy Halloween quotes for facebook halloween pumpkin ideas Happy Halloween 2016 Messages Happy Halloween 2016 sms Happy Halloween 2016 Status Happy Halloween 2016 Wishes Happy Halloween 2016 quotes
dIwali Wishes
by dIwali Wishes on Friday, Oct 14 2016 10:31:34 +00:00
Hello I see your blog its to much excellent thanks for shearing this deepawali Wishes
Nirmal kumar
by Nirmal kumar on Friday, Oct 14 2016 11:18:43 +00:00
clean tuts happy Diwali wishes Try - Happy Diwali Greeting maker
Diwali Images 2016
by Diwali Images 2016 on Friday, Oct 14 2016 14:08:24 +00:00
Payal
by Payal on Sunday, Oct 16 2016 13:17:04 +00:00
I am Gurgaon Escorts Services common with all the ways of life of a man. I am a Celebrity by career, I go to various places for my job to accomplish various persons and I take gratification in it. Click this link and seen Gurgaon Escorts
halloween Decorations
by halloween Decorations on Tuesday, Oct 18 2016 16:43:34 +00:00
rajRKO
by rajRKO on Wednesday, Oct 19 2016 09:26:30 +00:00
peacock rangoli designs images http://www.rangolidesignsimages.com/peacock-rangoli-designs-images
Asok
by Asok on Wednesday, Oct 19 2016 10:48:30 +00:00
happy
by happy on Wednesday, Oct 19 2016 10:50:50 +00:00
asok
by asok on Wednesday, Oct 19 2016 10:55:21 +00:00
rajRKO
by rajRKO on Thursday, Oct 20 2016 09:42:02 +00:00
rajRKO
by rajRKO on Friday, Oct 21 2016 07:36:03 +00:00
diwali rangoli patterns
by diwali rangoli patterns on Friday, Oct 21 2016 10:58:30 +00:00
I like your bolg diwali rangoli patterns thanks for sharing this
RIYO
by RIYO on Sunday, Oct 23 2016 14:23:02 +00:00
Download Latest Bollywood, Punjabi, English Music Albums, Hindi Movie Songs, Latest Hip Hop Single Tracks at 9xmsongs.com Mp3 Songs Free Download Mp3 Songs Download
rajRKO
by rajRKO on Tuesday, Oct 25 2016 06:47:15 +00:00
wifi hacker apk
by wifi hacker apk on Tuesday, Oct 25 2016 06:48:43 +00:00
good
zapya
by zapya on Tuesday, Oct 25 2016 11:23:16 +00:00
Download Zapya for PC to share files and folders easily from PC to other devices

Tags