Java and J2EE Tutorials, Jsp and Servlet Tutorials, Spring MVC, Solr, XML, JSON Examples, Hibernate & Struts 2 Hello World projects



Thursday, 24 July 2014

Integrate Neo4j (Graph DB) with Java – Neo4J with Java (Neo4J + Java)

In this article we will see, what is Neo4J and graph db and how to use Neo4J with Java, adding nodes, relationships, properties and much more, stay tight and go forward :)

In computer science a graph database is a database that uses graph structure to store data, with help of graph nodes, nodes properties and relationships in between nodes. Nodes represents entities like employee, person, item, salary .. etc. Properties holds information about the node, as in case of employee node properties are id, name, department etc.. The graph can be traversed using any graph traversal algorithm.

Relationships are represented by edges those connects different nodes to nodes or nodes to properties. Relationships can also have properties. Like a relationships “friend” between two person nodes with type “knows” can have relationship properties like “are-true-friend”, “fiends-since” etc.. and their values like “yes”, “1787” etc..

There are a number of different graph db projects, some of them are AllegroGraph, ArangoDB, Bitsy, DEX/Sparksee, GraphBase and Neo4j.


Neo4j graph db

Neo4j is a open source database implemented in Java, Neo4j is the most popular graph database of today. Neo4j is fully transactional Java persistent engine that stores data in graph node rather than tables. Installing Neo4j database in windows 7

Neo4j db can be used as embedded db to be used in your code, but it’s always a better practice to store full db server to learn it. Follow the steps below to download and install Neo4j db in your local machine and get it up:
1) Download an updated and appropriate release from http://www.neo4j.org/download.
2) Double click the setup and install db server as simple as other windows application.
3) Visit http://localhost:7474 to verify that the server instance is started and running correctly.


Integrating Neo4j with Java

Neo4j exposes all required API’s to integrate with Java applications, Neo4j accepts request and return response in Json format only. In the rest part of the application we will see how to create a node, add properties and relationships to db using Java code.

We need to add a Neo4j driver dependency to the project

  <dependency>
   <groupId>org.neo4j</groupId>
   <artifactId>neo4j</artifactId>
   <version>2.1.2</version>
  </dependency>
Neo4j exposes its functions using REST API’s in Json format, so we have to use any REST API client to interact with. I am using HttpCient libraries, but you are free to use any API as per your convenient.
  
<dependency>
   <groupId>commons-httpclient</groupId>
   <artifactId>commons-httpclient</artifactId>
   <version>3.1</version>
  </dependency>
  <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.1.3</version>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpmime</artifactId>
   <version>4.1.3</version>
   <scope>compile</scope>
  </dependency>


Checking if Neo4j DB server is up and running.

To check the server status we need to send a get request to server in the required format, if got 200 status code, it means everything is fine and server is running peacefully.

For rest of the blog we have referring server root with “SERVER_ROOT_URI” as:
final String SERVER_ROOT_URI = "http://localhost:7474";
        /*
  * checks if neo4j server is up and running, returns 200 if succeeded and
  * 500 otherwise
  */
 public int getNeo4jServerStatus(String SERVER_ROOT_URI) {
  int statusCode = 500;
  try {

   String url = SERVER_ROOT_URI;
   HttpClient client = new HttpClient();
   GetMethod getMethod = new GetMethod(url);
   statusCode = client.executeMethod(getMethod);
   getMethod.releaseConnection();
  } catch (Exception e) {
   System.out.println("Exception in connecting to neo4j DB : " + e);
  }

  return statusCode;
 }


Adding a node to Neo4j DB server using Java

We have to send a post request to server URI //db/data/node to make a node in Neo4j DB. In accepts POST request and returns JSON data.

Create node Request format
• POST http://localhost:7474/db/data/node
• Accept: application/json; charset=UTF-8

Create node Response format
• 201: Created
• Content-Type: application/json; charset=UTF-8
• Location: http://localhost:7474/db/data/node/89
        /*
  * adding a node to server root
  */
 public String addNode(String SERVER_ROOT_URI) {
  String serverResponse = null;
  String nodeLocation = null;
  try {
   String nodePointUrl = SERVER_ROOT_URI + "/db/data/node";
   HttpClient client = new HttpClient();
   PostMethod postMethod = new PostMethod(nodePointUrl);

   /**
    * set header information to post request
    */
   Header header = new Header();
   header.setName("content-type");
   header.setValue("application/json");
   header.setName("accept");
   header.setValue("application/json");
   postMethod.addRequestHeader(header);

   /**
    * set json payload to post request
    */
   // empty node in json format
   StringRequestEntity stringRequestEntity = new StringRequestEntity(
     "{}", "application/json", "UTF-8");
   postMethod.setRequestEntity(stringRequestEntity);
   int requestStatus = client.executeMethod(postMethod);
   serverResponse = postMethod.getResponseBodyAsString();
   Header locationHeader = postMethod.getResponseHeader("location");
   nodeLocation = locationHeader.getValue();
   postMethod.releaseConnection();
   System.out.println("Request Status : " + requestStatus);
   System.out.println("Node Location : " + nodeLocation);
   System.out.println("Server Response Json : " + serverResponse);
  } catch (Exception e) {
   System.out.println("Exception in adding a node to neo4j graph : "
     + e);
  }

  return nodeLocation;
 }
The code above is self explained, all we have done is make a POST request and send a empty JSON object. We can that verify the node by browsing to URL printed in “Node Location” in console. It would be in form of http://localhost:7474/db/data/node/1.


Adding properties to a Neo4J node using Java

Till now we have added a empty node to Neo4J server, lets add some properties to the node. The properties service is a PUT service and upon successful completion it returns “204 No Content” response. Like it’s create pear this service also accepts and sends Json data format.

Properties node Request format
• PUT http://localhost:7474/db/data/node/80/properties/foo
• Accept: application/json; charset=UTF-8
• Content-Type: application/json

Properties node Response format
• 204: No Content
        /*
  * adding properties to nodes
  */
 public void addProperty(String SERVER_ROOT_URI, String nodeLocationPath,
   String propertyName, String propertyValue) {

  try {
   String nodePointUrl = nodeLocationPath + "/properties/"
     + propertyName;
   HttpClient httpClient = new HttpClient();
   PutMethod putMethod = new PutMethod(nodePointUrl);

   /**
    * set headers
    */
   Header header = new Header();
   header.setName("content-type");
   header.setValue("application/json");
   header.setName("accept");
   header.setValue("application/json");
   putMethod.addRequestHeader(header);

   /**
    * set json payload
    */
   String jsonString = "\"" + propertyValue + "\"";
   StringRequestEntity requestEntity = new StringRequestEntity(
     jsonString, "application/json", "UTF-8");
   putMethod.setRequestEntity(requestEntity);
   int satusCode = httpClient.executeMethod(putMethod);

   putMethod.releaseConnection();
   System.out.println("Satus Code : " + satusCode);
  } catch (Exception e) {
   System.out.println("Exception in adding propery to node : " + e);
  }

 }
In the code above we have passed the node URI to which we need to add properties, once added the node you can check it using browser console of Neo4J.


Creating a relationship in Neo4J using Java

To create a relationship we uses URI /relationships, here nodeurl is the location of source node to which relationship is being created.

The web service accepts a POST request in json format and returns response in Json format. After successful completion of request you will get a 201 status code. The API also returns the relationship node location.

Relationship node Request format
• PUT http://localhost:7474/db/data/node/80/properties/foo
• Accept: application/json; charset=UTF-8
• Content-Type: application/json

Relationship node Response format
• 204: No Content
        /*
  * adding relationship between two nodes
  */
 public String addRelationship(String firstNodeLocation,
   String secondNodeLocation, String relationship,
   String relationAttributes) {
  String relationOutputJson = null;
  String relationLocation = null;
  try {
   String fromUrl = firstNodeLocation + "/relationships";

   String relationshipJson = generateJsonRelationship(
     secondNodeLocation, relationship, relationAttributes);

   System.out.println("Relationship Json : " + relationshipJson);

   HttpClient httpClient = new HttpClient();
   PostMethod mPost = new PostMethod(fromUrl);

   /**
    * set request headers
    */
   Header mtHeader = new Header();
   mtHeader.setName("content-type");
   mtHeader.setValue("application/json");
   mtHeader.setName("accept");
   mtHeader.setValue("application/json");
   mPost.addRequestHeader(mtHeader);

   /**
    * set request json payload
    */
   StringRequestEntity requestEntity = new StringRequestEntity(
     relationshipJson, "application/json", "UTF-8");
   mPost.setRequestEntity(requestEntity);
   int nodesatus = httpClient.executeMethod(mPost);
   relationOutputJson = mPost.getResponseBodyAsString();
   Header locationHeader = mPost.getResponseHeader("location");
   relationLocation = locationHeader.getValue();
   mPost.releaseConnection();
   System.out.println("Node Satus : " + nodesatus);
   System.out.println("Relation node Location : " + relationLocation);
   System.out.println("output : " + relationOutputJson);
  } catch (Exception e) {
   System.out.println("Exception in adding relationship node in neo4j : " + e);
  }

  return relationLocation;

 }

 /*
  * used to create relationship json in required format
  */
 private String generateJsonRelationship(String secondNodeLocation,
   String relationship, String relationAttributes) {

  StringBuilder sb = new StringBuilder();
  sb.append("{ \"to\" : \"");
  sb.append(secondNodeLocation);
  sb.append("\", ");

  sb.append("\"type\" : \"");
  sb.append(relationship);
  if (relationAttributes == null || relationAttributes.length() < 1) {
   sb.append("\"");
  } else {
   sb.append("\", \"data\" : " + relationAttributes);

  }

  sb.append(" }");
  return sb.toString();
 }


Adding properties to a relationship in Neo4J using Java

Here we are done with adding nodes and a relationship in between nodes, now we can add properties to relationships as well. Properties can be added to a relationship making a put request to /properties where relationshiplocation is the location of relationship in db server.

Relationship node Request format
• PUT http://localhost:7474/db/data/relationship/113/properties
• Accept: application/json; charset=UTF-8
• Content-Type: application/json

Relationship node Response format
• 204: No Content
public void addPropertyToRelations(String relationshipLocationPath,
   String propertyName, String propertyValue) {

  try {
   String relPropUrl = relationshipLocationPath + "/properties";
   HttpClient httpClient = new HttpClient();
   PutMethod putMethod = new PutMethod(relPropUrl);

   /**
    * set request headers
    */
   Header header = new Header();
   header.setName("content-type");
   header.setValue("application/json");
   header.setName("accept");
   header.setValue("application/json");
   putMethod.addRequestHeader(header);

   /**
    * set request json payload
    */
   String jsonString = convertToNameValueJson(propertyName,
     propertyValue);
   StringRequestEntity requestEntity = new StringRequestEntity(
     jsonString, "application/json", "UTF-8");
   putMethod.setRequestEntity(requestEntity);
   int satusCode = httpClient.executeMethod(putMethod);

   putMethod.releaseConnection();
   System.out.println("Satus Code : " + satusCode);
  } catch (Exception e) {
   System.out
     .println("Exception in addding properties to a relation in neo4j : "
       + e);
  }

 }

 private String convertToNameValueJson(String name, String value) {
  return String.format("{ \"%s\" : \"%s\" }", name, value);
 }
Done, till now we have seen, how to install and setup Neo4J in Windows and integrate Neo4j with Java. Lets see the folks running now, here are two complete files used in this project one is consists of operations and other file is having main() to perform them.

\src\main\java\com\beingjavaguys\graphdb\ServerUtils.java
package com.beingjavaguys.graphdb;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

/**
 * @author Nagesh.Chauhan
 * 
 */
public class ServerUtils {
 /*
  * checks if neo4j server is up and running, returns 200 if succeeded and
  * 500 otherwise
  */
 public int getNeo4jServerStatus(String SERVER_ROOT_URI) {
  int statusCode = 500;
  try {

   String url = SERVER_ROOT_URI;
   HttpClient client = new HttpClient();
   GetMethod getMethod = new GetMethod(url);
   statusCode = client.executeMethod(getMethod);
   getMethod.releaseConnection();
  } catch (Exception e) {
   System.out.println("Exception in connecting to neo4j DB : " + e);
  }

  return statusCode;
 }

 /*
  * adding a node to server root
  */
 public String addNode(String SERVER_ROOT_URI) {
  String serverResponse = null;
  String nodeLocation = null;
  try {
   String nodePointUrl = SERVER_ROOT_URI + "/db/data/node";
   HttpClient client = new HttpClient();
   PostMethod postMethod = new PostMethod(nodePointUrl);

   /**
    * set header information to post request
    */
   Header header = new Header();
   header.setName("content-type");
   header.setValue("application/json");
   header.setName("accept");
   header.setValue("application/json");
   postMethod.addRequestHeader(header);

   /**
    * set json payload to post request
    */
   // empty node in json format
   StringRequestEntity stringRequestEntity = new StringRequestEntity(
     "{}", "application/json", "UTF-8");
   postMethod.setRequestEntity(stringRequestEntity);
   int requestStatus = client.executeMethod(postMethod);
   serverResponse = postMethod.getResponseBodyAsString();
   Header locationHeader = postMethod.getResponseHeader("location");
   nodeLocation = locationHeader.getValue();
   postMethod.releaseConnection();
   System.out.println("Request Status : " + requestStatus);
   System.out.println("Node Location : " + nodeLocation);
   System.out.println("Server Response Json : " + serverResponse);
  } catch (Exception e) {
   System.out.println("Exception in adding a node to neo4j graph : "
     + e);
  }

  return nodeLocation;
 }

 /*
  * adding properties to nodes
  */
 public void addProperty(String SERVER_ROOT_URI, String nodeLocationPath,
   String propertyName, String propertyValue) {

  try {
   String nodePointUrl = nodeLocationPath + "/properties/"
     + propertyName;
   HttpClient httpClient = new HttpClient();
   PutMethod putMethod = new PutMethod(nodePointUrl);

   /**
    * set headers
    */
   Header header = new Header();
   header.setName("content-type");
   header.setValue("application/json");
   header.setName("accept");
   header.setValue("application/json");
   putMethod.addRequestHeader(header);

   /**
    * set json payload
    */
   String jsonString = "\"" + propertyValue + "\"";
   StringRequestEntity requestEntity = new StringRequestEntity(
     jsonString, "application/json", "UTF-8");
   putMethod.setRequestEntity(requestEntity);
   int satusCode = httpClient.executeMethod(putMethod);

   putMethod.releaseConnection();
   System.out.println("Satus Code : " + satusCode);
  } catch (Exception e) {
   System.out.println("Exception in adding propery to node : " + e);
  }

 }

 /*
  * adding relationship between two nodes
  */
 public String addRelationship(String firstNodeLocation,
   String secondNodeLocation, String relationship,
   String relationAttributes) {
  String relationOutputJson = null;
  String relationLocation = null;
  try {
   String fromUrl = firstNodeLocation + "/relationships";

   String relationshipJson = generateJsonRelationship(
     secondNodeLocation, relationship, relationAttributes);

   System.out.println("Relationship Json : " + relationshipJson);

   HttpClient httpClient = new HttpClient();
   PostMethod mPost = new PostMethod(fromUrl);

   /**
    * set request headers
    */
   Header mtHeader = new Header();
   mtHeader.setName("content-type");
   mtHeader.setValue("application/json");
   mtHeader.setName("accept");
   mtHeader.setValue("application/json");
   mPost.addRequestHeader(mtHeader);

   /**
    * set request json payload
    */
   StringRequestEntity requestEntity = new StringRequestEntity(
     relationshipJson, "application/json", "UTF-8");
   mPost.setRequestEntity(requestEntity);
   int nodesatus = httpClient.executeMethod(mPost);
   relationOutputJson = mPost.getResponseBodyAsString();
   Header locationHeader = mPost.getResponseHeader("location");
   relationLocation = locationHeader.getValue();
   mPost.releaseConnection();
   System.out.println("Node Satus : " + nodesatus);
   System.out.println("Relation node Location : " + relationLocation);
   System.out.println("output : " + relationOutputJson);
  } catch (Exception e) {
   System.out
     .println("Exception in adding relationship node in neo4j : "
       + e);
  }

  return relationLocation;

 }

 /*
  * used to create relationship json in required format
  */
 private String generateJsonRelationship(String secondNodeLocation,
   String relationship, String relationAttributes) {

  StringBuilder sb = new StringBuilder();
  sb.append("{ \"to\" : \"");
  sb.append(secondNodeLocation);
  sb.append("\", ");

  sb.append("\"type\" : \"");
  sb.append(relationship);
  if (relationAttributes == null || relationAttributes.length() < 1) {
   sb.append("\"");
  } else {
   sb.append("\", \"data\" : " + relationAttributes);

  }

  sb.append(" }");
  return sb.toString();
 }

 public void addPropertyToRelations(String relationshipLocationPath,
   String propertyName, String propertyValue) {

  try {
   String relPropUrl = relationshipLocationPath + "/properties";
   HttpClient httpClient = new HttpClient();
   PutMethod putMethod = new PutMethod(relPropUrl);

   /**
    * set request headers
    */
   Header header = new Header();
   header.setName("content-type");
   header.setValue("application/json");
   header.setName("accept");
   header.setValue("application/json");
   putMethod.addRequestHeader(header);

   /**
    * set request json payload
    */
   String jsonString = convertToNameValueJson(propertyName,
     propertyValue);
   StringRequestEntity requestEntity = new StringRequestEntity(
     jsonString, "application/json", "UTF-8");
   putMethod.setRequestEntity(requestEntity);
   int satusCode = httpClient.executeMethod(putMethod);

   putMethod.releaseConnection();
   System.out.println("Satus Code : " + satusCode);
  } catch (Exception e) {
   System.out
     .println("Exception in addding properties to a relation in neo4j : "
       + e);
  }

 }

 private String convertToNameValueJson(String name, String value) {
  return String.format("{ \"%s\" : \"%s\" }", name, value);
 }
}


\src\main\java\com\beingjavaguys\graphdb\App.java
package com.beingjavaguys.graphdb;

/**
 * @author Nagesh.Chauhan
 * 
 */
public class App {
 public static void main(String[] args) {
  final String SERVER_ROOT_URI = "http://localhost:7474";
  ServerUtils serverUtils = new ServerUtils();

  // getting server status
  int serverStatusCode = serverUtils
    .getNeo4jServerStatus(SERVER_ROOT_URI);

  if (serverStatusCode == 200) {
   // adding a blank node to neo4j db server
   String firstNodeLocation = serverUtils.addNode(SERVER_ROOT_URI);
   System.out.println("First Node Location: " + firstNodeLocation);

   // adding another blank node to neo4j db server
   String secondNodeLocation = serverUtils.addNode(SERVER_ROOT_URI);
   System.out.println("Second Node Location: " + secondNodeLocation);

   // adding properties to first node in server
   serverUtils.addProperty(SERVER_ROOT_URI, firstNodeLocation, "name",
     "andrew");
   serverUtils.addProperty(SERVER_ROOT_URI, firstNodeLocation,
     "email", "andrew@java.com");
   serverUtils.addProperty(SERVER_ROOT_URI, firstNodeLocation,
     "phone", "7876754346");

   // adding properties to second node in server
   serverUtils.addProperty(SERVER_ROOT_URI, secondNodeLocation,
     "name", "smith");
   serverUtils.addProperty(SERVER_ROOT_URI, secondNodeLocation,
     "email", "smith@java.com");
   serverUtils.addProperty(SERVER_ROOT_URI, secondNodeLocation,
     "phone", "8787653454");

   // adding a relationship in between two nodes
   String relationAttributes = "{ \"bestfriends\" : \"yes\",\"since\" : \"2005\" }";
   String relationshipLocation = serverUtils.addRelationship(
     firstNodeLocation, secondNodeLocation, "friend",
     relationAttributes);
   System.out
     .println("Relationship Location: " + relationshipLocation);

   // adding property to existing relation
   serverUtils.addPropertyToRelations(relationshipLocation, "common",
     "behavior");
  }
 }

}


Run Java application, if everything goes right you can browse nodes creted and relationship created using Location URI's(node numbers may be different refer your console to get URI's) like:

Node URI Like: http://localhost:7474/db/data/node/19



Relationship URI Like: http://localhost:7474/db/data/relationship/4



We came to know how to add node, relationships and properties to Neo4J db server using Java. By now you are able to understand the functioning of Neo4J API for Java. Other updating and deleting operations and query database can be performed like this by using appropriate JSON format and request type. There are a number of other useful operations like Updating and Deleting nodes and relationships and their properties. We will see how to query Neo4J db using Java in upcoming blogs.

Download complete Project : Download Link










Thanks for reading !
Being Java Guys Team

Download "Integrate Neo4j (Graph DB) with Java Example Project" from "SkyDrive"




2 comments:

  1. Thank you so much for sharing this project with download link. I will going to run it, if everything okay then you are person who solve out my major project headache.

    ReplyDelete
  2. Nice one... Very useful article for my project...

    ReplyDelete

Like Us on Facebook


Like Us On Google+



Contact

Email: neel4soft@gmail.com
Skype: neel4soft