In this post, we will go through examples of neo4j simple and complex queries.
We will go through some neo4j samples and some scenarios. Let’s begin with the basics.
Create Nodes with properties:
Query To Create Simple Nodes:
1 2 3 4 5 6 7 8 |
> CREATE (n:Actor { name : "Keanu Reeves", Age : 50, Gender:"Male" , isAlive : true }); > CREATE (n:Actor { name : "Drew Barrymore", Age : 39, Gender:"Female" ,isAlive : true }); > CREATE (n:Actor { name : "Paris Hilton", Age: 33, Gender:"Female" , isAlive : true }); |
Above query will create nodes of type Actor.
Query To add a new property to existing Node:
MATCH (actor:Actor) SET actor.friendsCount = 0 RETURN actor;
Above query will simply add property friendsCount to all Actor nodes.
Create Relationship between Nodes in Neo4j:
Assuming that you all are familiar with Twitter and Instagram where you follow people of your choice, the relationship “follows” ( i.e. for e.g one actor following other actor) has properties
FollowingStatus: (pending, approve, rejected)
Let take an example, Drew Barrymore starts following Paris Hilton, so she just sends a request.
1 2 3 |
> MATCH (actor:Actor),(actor2:Actor) WHERE actor.name = "Drew Barrymore" and actor2.name = "Paris Hilton" CREATE (actor)-[rel:FOLLOW{status:"pending"}]->(actor2) RETURN rel; |
Above query can get you in trouble because whenever you execute it, it will create multiple relations between the same node, and can cause confusion. To solve this we can use UNIQUE keyword as shown below.
1 2 3 |
> MATCH (actor:Actor),(actor2:Actor) WHERE actor.name = "Drew Barrymore" and actor2.name = "Paris Hilton" CREATE UNIQUE (actor)-[rel:FOLLOW{status:"pending"}]->(actor2) RETURN rel; |
Suppose, on top of this you also want to log the information like whenever you try to update the same relationship you just want to log a timestamp or a flag. For that we can use the below query.
1 2 3 4 5 6 |
> MATCH (actor:Actor),(actor2:Actor) WHERE actor.name = "Drew Barrymore" AND actor2.name = "Paris Hilton" MERGE (actor)-[rel:FOLLOW{status:"pending"}]->(actor2) ON CREATE SET rel.createTime=140123120, rel.updateTime=140123120 ON MATCH SET rel.updateTime=140123120 RETURN rel; |
Suppose, if you want to update the status value only, considering that Paris Hilton has accepted here follow request.
1 2 3 4 |
> Match ((actor:Actor)-[follow:FOLLOW {status:"pending"}]->(actor2:Actor)) WHERE actor.name = "Drew Barrymore" and actor2.name = "Paris Hilton" SET follow.status = "accepted", actor.friendsCount = coalesce(actor.friendsCount,0) + 1, actor2.friendsCount = coalesce(actor2.friendsCount,0) + 1 RETURN follow; |
Above query will update the Follow request status property from pending to accepted if and only if it is pending. And at the same time will also update the friendscount of both the node.
One can also make use of CASE feature of Neo4j as seen below.
Conditional update:
1 2 3 4 5 |
> Match ((actor:Actor)-[follow:FOLLOW]->(actor2:Actor)) WHERE actor.name = "Drew Barrymore" and actor2.name = "Paris Hilton" SET follow.status = CASE WHEN follow.status = "pending" THEN "accepted" ELSE follow.status END RETURN follow; |
The above query works the same way as the previous one, but there are many scenarios in which the above query can help you like adding multiple case scenarios.
Note: Don’t forget to put END after case.
Data Retrieval in Neo4j
By using above scenario, lets create
nodes of Movie with property “name”( name of the movie) and “likes”(number of likes).
An actor can have LIKE relation with node Movie. This scenario can be represented using the Figure below.
Blue nodes are Actors and Orange ones are Movies.
37 (Actor Node): Drew Barrymore
46 (Actor Node): Paris Hilton
67 (Movie Node): ET
rest of nodes are other movies that are liked by Paris Hilton.
Basic Retrieval of Nodes by its Property:
1 |
> MATCH (n:Actor {Age:39}) return n; |
We can clearly see that the output of the above query will be the node of Drew Barrymore.
1 |
> MATCH (n:Actor) where n.Age > 19 return n; |
One more example. This query will output all the actor nodes with Age greater than 19.
Normally, you won’t find any trouble in above query, but in real word, there will be a need of some complex retrieval combining properties and node status.
Complex Retrieval of Nodes by its Property:
Suppose, you want to suggest your actor some moview.
In our data lets assume that Drew Barrymore is following (Approved) Paris Hilton.
Drew Barrymore has already liked “ET” movie and Paris Hilton has liked “ET”, “Grown Ups”, “The Grudge”, “House Of Wax”.
Now, you want data to be like,
NAME_OF_MOVIE | WATCHED | NO_OF_LIKES
___________________________________________________________
Grown Ups NOT WATCHED 10
Matrix NOT WATCHED 3
The Grudge NOT WATCHED 2
ET WATCHED 1
House Of Wax NOT WATCHED 1
To fetch data as shown above, one can use example query like the following.
1 2 3 4 5 6 7 8 |
> MATCH (actor1:Actor)-[follow:FOLLOW]->(actor2:Actor)-[like1:LIKE]->(movie:Movie) with actor1,movie OPTIONAL MATCH (actor1)-[like2:LIKE]->(movie) with actor1, movie, like2 WHERE actor1.name = "Drew Barrymore" RETURN DISTINCT movie.name AS NAME_OF_MOVIE, CASE WHEN like2 IS NULL THEN "NOT WATCHED" ELSE "WATCHED" END AS WATCHED, movie.likes AS NO_OF_LIKE ORDER BY movie.likes DESC |
Output of which is,
Thank you for reading and please feel free to comment if you encounter any difficulties or specific scenarios.
Also if you like to set up High Availability Cluster of Neo4j for your organization or personal use please have a look at http://neo4j.com/docs/stable/ha-how.html.