Beliebte Suchanfragen

Cloud Native

DevOps

IT-Security

Agile Methoden

Java

|
//

Spring Data – Part 5: Neo4j

27.2.2012 | 4 minutes of reading time

Introduction

Neo4j [1 ] is a high-performance NoSQL [2 ] datastore specialized in persisting graphs. A graph [3 ] is data structure consisting of finite sets of vertices and edges, where an edge is a connection between two vertices. Graphs are used to represent relationsiphs or connections (edges) between domain objects (vertices). Social networks are an application of a graph data structure.

Neo4j

After downloading the community edition of Neo4j [4 ] you just unzip the distribution package to a folder NEO4J_HOME and start the server with

1${NEO4J_HOME}/bin/Neo4J.bat

(on a Windows OS). By default, the web admin interface can be found at http://localhost:7474/webadmin . which includes a web based shell. More important for a start is the “Data brower” tab where you can add nodes and relationship between them. There is also a search function that renders the result graphs.

Spring Data Neo4j

First of all, we let Maven download the latest stable release version of Spring Data Neo4j:

1<dependency>
2   <groupId>org.springframework.data</groupId>
3   <artifactId>spring-data-neo4j</artifactId>
4   <version>2.0.0.RELEASE</version>
5</dependency>

We want to access our Neo4j server via remote REST calls, so we have to add this optinal dependency:

1<dependency>
2   <groupId>org.springframework.data</groupId>
3   <artifactId>spring-data-neo4j-rest</artifactId>
4   <version>2.0.0.RELEASE</version>
5</dependency>

As with all the Spring Data projects, configuration is quite simple by special XML name spaces. In our case neo4j does the job:

1<!-- REST Connection to Neo4j server -->
2<bean id="restGraphDatabase" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
3  <constructor-arg value="http://localhost:7474/db/data/" />
4</bean>
5 
6<!-- Neo4j configuration (creates Neo4jTemplate) -->
7<neo4j:config graphDatabaseService="restGraphDatabase" />
8 
9<!-- Package w/ automagic repositories -->
10<neo4j:repositories base-package="neo4j" />

We provide the base URL for the REST access and wire this service into the Neo4j configuration.

The basic idea behind the Spring Data project is to write only interface methods to define your custom finders. Spring will inject an appropriate implementation at runtime which also provides all CRUD functionality. To enable this in your application, you have to configure the package with the node.

Domain Object

As in the previous posts of this series we’ll persist some simple user objects. The Neo4j flavour of this class may look like this:

1/** Simple user class. */
2@NodeEntity public class User {
3 
4  @GraphId Long id;
5 
6  @Indexed private String login;
7 
8  private String fullName;
9 
10  private Date lastLogin;
11 
12  @RelatedTo(type = "knows", direction = Direction.OUTGOING)
13  Set<User> friends;	
14  ...

To enable persistence with Neo4j, you use the @NodeEntity at the class level. The unique id of every node has to be annotated with @GraphId. You don’t have to care about the numbering, Neo4j allocates the values. Indices can be define by using the @Indexed annotation.

To define a basic relation between the users named knows (expressing that user U knows user V), we used the annotation @RelatedTo at a set of users.

The following example is based on a graph of users. We’ll have n users. Each user U_i knows user U_j (for all 0 <= i < j <= n). User root knows them all. For n = 3 the graph looks like this:

There is also a standalone RCP application called Neoclipse [6 ] for graph visualization.

Repository

To define a simple repository with all the CRUD methods we need a single line of code:

1public interface UserRepository extends GraphRepository<User> {}

We’ll add some custom finders later. Right now, we persist the above graph by using the method save:

1...
2// build graph
3for ( int i = 0; i < user.length; i++ ) {
4  root.knows(user[i]);
5  for ( int j = i; j < user.length; j++ ) {
6    user[i].knows(user[j]);
7  }
8}
9 
10// save nodes
11for ( int i = 0; i < user.length; i++ ) {
12  repo.save(user[i]);
13}
14repo.save( root );

We added a convinience method knows(...) to the user class which adds the given user to the set of known users to make the code better readable. If you know the id of a saved node, you can display it in your browser (actually, it’s a REST get call with HTML output):

1http://localhost:7474/db/data/node/98

To find a single node via the Spring Data API, use the standard finder method findOne(long):

1User root = repo.findOne(rootId);

Time to add some custom finders to our repository:

1public interface UserRepository extends GraphRepository<User> {
2 
3  User findByLogin(String login);
4 
5  @Query("START root=node:User(login = 'root') MATCH root-[:knows]->friends RETURN friends")
6  List<User> findFriendsOfRoot();
7}

The first query returns a single node by matching the node’s login property. It is also possible to write your own Cypher [5 ] queries with the @Query annotation. The second query does so and returns all users known by the root user.

The complete source code of the example can be found a github .

Summary

That’s it for today. I showed you how to install and run your standalone Neo4j server instance. We set up and configured a Maven based Spring Data Neo4j project. After persisting a small example graph, we wrote some custom finders and even used the Cypher query language.

Of course, this was only a short glimpse into the Neo4j universe. I hope you enjoyed it. Browse the Neo4j site to discover more, including embedded database with transaction support and geospatial queries.

Spring Data Project

These are my other posts covering the Spring Data project:

Part 4: Geospatial Queries with Spring Data Mongo DB
Part 3: Spring Data Mongo DB
Part 2: Spring Data JPA
Part 1: Spring Data Commons

Expect upcoming blog posts on Spring Data Redis and Spring GemFire

References

[1] Neo4j
[2] NoSQL databases
[3] Graphs
[4] Neo4j Download
[5] Cypher Cookbook
[6] Neoclipse Download

|

share post

Likes

0

//

More articles in this subject area

Discover exciting further topics and let the codecentric world inspire you.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.