Neo4j Implement PathExpander Sequence

Hi All,

After took some rest for a while, I would like to post some kind of simple implementation of pathexpander since it is really hard to find the sample. I hope it could give some ideas on how the pathexpander works.

As you know that each node in the graph could have many relationship types to other nodes, So when you use the neo4j traversal you must be interested to how to choose the path to be traversed effectively. Neo4j provides pathexpander and evaluators to manage which nodes to be included but I do really love to use the pathexpander to implement on which relationship to be traversed and evaluator only to manage traversal depth, node field check and etc.

I used to have the code integrated with the springdata as the integrator between my code and neo4j. So the code would be as below.

1. Setup the maven with .pom. Put attention to the neo4j dependency, Although I put there neo4j rest, I dont use it since some of the function in the evaluator and pathexpander have not yet implemented. So I decided to use the embedded graphdataabse which mostly of the functions are ready to do the task.

</code></pre>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

<groupId>neo4j</groupId>
 <artifactId>mytraversal</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

<name>mytraversal</name>
 <url>http://maven.apache.org</url>

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

<repositories>
 <repository>
 <snapshots>
 <enabled>false</enabled>
 </snapshots>
 <id>central</id>
 <name>Maven Repository Switchboard</name>
 <url>http://repo1.maven.org/maven2</url>
 </repository>

<repository>
 <id>springsource-repo</id>
 <name>SpringSource Repository</name>
 <url>http://repo.springsource.org/release</url>
 </repository>
 <repository>
 <id>spring-snapshot</id>
 <name>Spring Maven SNAPSHOT Repository</name>
 <url>http://repo.springsource.org/libs-milestone</url>
 </repository>

</repositories>
 <dependencies>
 <dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib</artifactId>
 <version>3.0</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>3.2.3.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>3.2.3.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-validator</artifactId>
 <version>5.0.1.Final</version>
 </dependency>
 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.17</version>
 </dependency>
 <dependency>
 <groupId>org.springframework.data</groupId>
 <artifactId>spring-data-neo4j-rest</artifactId>
 <version>2.2.2.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework.data</groupId>
 <artifactId>spring-data-neo4j</artifactId>
 <version>2.3.0.M1</version>
 </dependency>
 </dependencies>
</project>

<code>

2. Create the applicationContext-spring.xml to manage the connection and bean creation for the neo4j to talk to springdata. Today I don’t use the rest server but the embedded graph to get full functionality of the springdata.

</span>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<context:spring-configured />
 <context:annotation-config />
 <context:component-scan base-package="neo4j.mytraversal" />
 <neo4j:repositories base-package="neo4j.mytraversal" />

<neo4j:config
 storeDirectory="C://Users//Rio Asmara Suryadi//Documents//ne4j//neo4j-community-1.9.2//data//graph.db" />
</beans>

3. Create the necessary file as below in the picture where I will show you the full code in this text traversal

4. Create class Runner as the as the object to execute the traversal

package neo4j.mytraversal;

import java.util.Iterator;
import java.util.List;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.traversal.Evaluation;
import org.neo4j.graphdb.traversal.Evaluator;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.kernel.StandardExpander;
import org.neo4j.kernel.Uniqueness;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.support.Neo4jTemplate;

public class Runner {

enum Rels implements RelationshipType {
 BUY
 }

@Autowired
 Neo4jTemplate template;

public void check() {
 final MeExpander test = new MeExpander();
 test.addRelationName("BUY");
 test.addRelationName("PURCHASED_ITEM");
 if (template != null) {
 TraversalDescription desc = template.traversalDescription()
 .breadthFirst().evaluator(new Evaluator() {
 public Evaluation evaluate(Path path) {
 if (path.length() == test.getSize()) {
 return Evaluation.INCLUDE_AND_PRUNE;
 }
 return Evaluation.EXCLUDE_AND_CONTINUE;
 }
 }).expand(test);

long start_time = System.currentTimeMillis();
 Iterator<Path> path = desc.traverse(template.getNode(1)).iterator();

while (path.hasNext()) {
 nodePropertyPrint(path.next().endNode());
 }

long end_time = System.currentTimeMillis();
 System.out.println("Traversal Time : "
 + String.valueOf(end_time - start_time) + " ms");

}

}

public void nodePropertyPrint(Node node) {
 Iterator<String> it = node.getPropertyKeys().iterator();
 while (it.hasNext()) {
 String field = it.next();
 System.out.println(field + ":" + node.getProperty(field));
 }

}

}

5. Implementing the traversal, Create the MeExpander class. MeExpander.class is java class which implement the pathexpander. You need to implement the “expand” function as below

</pre>
package neo4j.mytraversal;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.PathExpander;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.traversal.BranchState;

public class MeExpander implements PathExpander {

List<DynamicRelationshipType> dynamicRelationshipTypes;

public MeExpander() {
 dynamicRelationshipTypes = new ArrayList<DynamicRelationshipType>();
 }

public Iterable expand(Path path, BranchState state) {
 return path.endNode().getRelationships(Direction.OUTGOING,
 dynamicRelationshipTypes.get(path.length()));
 }

public void addRelationName(String name) {
 dynamicRelationshipTypes.add(DynamicRelationshipType.withName(name));
 }

 int getSize(){
 return dynamicRelationshipTypes.size();
 }

public PathExpander reverse() {
 // TODO Auto-generated method stub
 return null;
 }

}
<pre>

6. Here is the screen capture of my graph database. Just focus to the node called Rio and its relationship. So whenever I run the code it will start from the node Rio and traverse to the depth 2 and return the node in the depth 2.

GraphCapture

7. So the output of the this simple apps is

CONSOLE OUT

name:Supermie
Traversal Time : 25 ms

Vaadin + Springdata + Neo4j Basic Conf with Spring Context

Hi all, Recently I checked out the Vaadin web and browsed the add-on directory. Wow it looks so fun to see this framework is getting bigger since alot of new add-on are coming in.

This time I am going to show the basic configuration for Vaadin + Springdata and Neo4j. I have post this kind of information in my previous post but in this tutorial is quite different since this basic configuration will use the spring contect rather than Vaadin’s

As usual my web application server is based on JBoss AS 7 so that I expected that you have had the basic knowledge of JBoss AS basic configuration

OK Lets get it start

1. Open your eclipse and start your JBoss AS

2. Create the vaadin project via Maven

3. Manage the POM.xml and setup as the entry below

<?xml version=”1.0″ encoding=”UTF-8″?>
<project xmlns=”http://maven.apache.org/POM/4.0.0&#8243; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”&gt;
<modelVersion>4.0.0</modelVersion>
<groupId>study</groupId>
<artifactId>springIntegration</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>Vaadin Web Application</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<vaadin.version>6.8.2</vaadin.version>
<gwt.version>2.3.0</gwt.version>
<gwt.plugin.version>2.2.0</gwt.plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshot</id>
<name>Spring Maven SNAPSHOT Repository</name>
<url>http://repo.springsource.org/libs-milestone</url&gt;
</repository>
<repository>
<id>vaadin-snapshots</id>
<url>http://oss.sonatype.org/content/repositories/vaadin-snapshots/</url&gt;
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>neo4j-release-repository</id>
<name>Neo4j Maven 2 release repository</name>
<url>http://m2.neo4j.org/releases</url&gt;
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url&gt;
</repository>
<repository>
<id>springsource-repo</id>
<name>SpringSource Repository</name>
<url>http://repo.springsource.org/release</url&gt;
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin</artifactId>
<version>${vaadin.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-rest</artifactId>
<version>2.1.0.RC3</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-rest-graphdb</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jsp-api</artifactId>
<version>6.0.35</version>
</dependency>
<dependency>
<groupId>org.dellroad</groupId>
<artifactId>dellroad-stuff</artifactId>
<version>1.0.507</version>
</dependency>
</dependencies>
</project>

4. Create file for the spring application-context.xml under the WEB-INF/classes

<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xmlns=”http://java.sun.com/xml/ns/javaee&#8221; xmlns:web=”http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&#8221;
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&#8221;
id=”WebApp_ID” version=”2.5″>
<display-name>Vaadin Web Application</display-name>
<context-param>
<description>Vaadin production mode</description>
<param-name>productionMode</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-spring.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>Vaadin Application Servlet</servlet-name>
<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>study.springIntegration.HelloWorld</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Vaadin Application Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

6. Yes all the configuration that you need it is now done and what you need is to create the hellowworld application

package study.springIntegration;

import org.dellroad.stuff.vaadin.SpringContextApplication;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.context.ConfigurableWebApplicationContext;

import com.vaadin.ui.Label;
import com.vaadin.ui.Window;

public class HelloWorld extends SpringContextApplication implements
BeanFactoryAware, InitializingBean, DisposableBean {
public void destroy() throws Exception {
// TODO Auto-generated method stub

}

public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub

}

public void setBeanFactory(BeanFactory arg0) throws BeansException {
// TODO Auto-generated method stub

}

@Override
protected void initSpringApplication(ConfigurableWebApplicationContext arg0) {
// TODO Auto-generated method stub
Window mainWindow = new Window(“Vaadin+Spring Demo #3”);
Label test = new Label();
test.setValue(“Hahahah”);
mainWindow.addComponent(test);
setMainWindow(mainWindow);
}

}

That is all the basic configuration for the Vaadin application that uses the spring context that is combined with the neo4j installation. Be careful that you should use at least the neo4j version 2.1 to be able to start the spring context unless you will face error in creation of bean REST in neo4j.

Graph Database (Neo4j)

In the late of 2011, I’m looking for a new database solution that do not rely on RDBMS and ORM for the object oriented data store. I was firstly introduced an NoSQL database called mongoDB that is quite impressive for object oriented data store. The learning curve for the database is very fast due to its simplicity. But looking at this and to the variation of the data that I’m going to store that has relationship then the MongoDB will not satisfy me with a simple and efficient way. I looked to another NoSQL database that based on the Graph, WOW… My first impression was good and not as simple as MongoDB from the document based database.

Finally I found Neo4j that is well known publicly to support the graph database. For some reasons I fell in love with this type of database. After trying a couple home project with the pure Neo4j API, I feel so classic working with API provided, I remember that I worked on project that use POSIX framwork.

Finding the solution for the Neo4j wrapper took me all around in the google and finally I found that Spring Data is the only one framework that is now being developed for serious project. So in order to really implement Neo4j for serious enterprise application you should master Spring data. I took sometimes to learn Spring in combination with Vaadin,

Finally, I can master these three frameworks to support my software development. It is feel good that you can use the high end technology and really implement it in my projects.