Introduction
Neo4j [1 ] ist ein hochperformanter NoSQL [2 ] Datastore, der auf die Verarbeitung von Graphen spezialisiert ist. Ein Graph [3 ] ist eine Datenstruktur, die aus einer endlichen Menge von Knoten und Kanten besteht, wobei eine Kante eine Verbindung zwischen zwei Knoten ist. Graphen werden verwendet, um Beziehungen oder Verbindungen (Kanten) zwischen Domain-Objekten (Knoten) zu repräsentieren. Soziale Netzwerke stellen einen Anwendungsfall dieser Datenstruktur dar.
Neo4j
Nach dem Download der Community Edition von Neo4j [4 ] wird das ZIP in einen Ordner NEO4J_HOME entpackt und der Server mit
1${NEO4J_HOME}/bin/Neo4J.bat
gestartet (auf einem Windows OS). Standardmäßig kann die Admin-Oberfläche unter http://localhost:7474/webadmin zugegriffen werden. Sie enthält u.a. eine Web-basierte Shell. Für den Anfang kann man mit den „Data browser“ manuell Knoten und Relationen einfügen und sich auch graphisch darstellen lassen.
Spring Data Neo4j
Zunächst lassen wir Maven die aktuelle Version von Spring Data Neo4j herunterladen:
1<dependency> 2 <groupId>org.springframework.data</groupId> 3 <artifactId>spring-data-neo4j</artifactId> 4 <version>2.0.0.RELEASE</version> 5</dependency>
Da wir Neo4j per Remote REST Call zugreifen wollen, benötigen wir diese optionale Abhängigkeit:
1<dependency> 2 <groupId>org.springframework.data</groupId> 3 <artifactId>spring-data-neo4j-rest</artifactId> 4 <version>2.0.0.RELEASE</version> 5</dependency>
Wie bei allen Spring Data Projekten ist die Konfiguration über spezielle XML Namensräume sehr einfach. Wir verwenden den Namensraum neo4j
:
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" />
Wir geben die Basis-URL für den REST-Zugriff an und verwenden diesen Service für die weitere Neo4j-Konfiguration.
Die grundsätzliche Idee hinter Spring Data ist, eigene Finder-Methode nur als Interface-Methode zu beschreiben. Spring stellt dann zur Laufzeit eine geeignete Implementierung samt aller gängigen CRUD-Operationen zur Verfügung. Um dies in einer Anwendung zu nutzen, muss noch das Paket mit diesen Interfaces über konfiguriert werden.
Domain Object
Wie in den vorangegangenen Beiträge in dieser Blog-Serie werden wir einige einfach User-Objekte abspeichern. Die Neo4j-Version davon kann so aussehen:
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 ...
Um die Neo4j-Persistenz zu nutzen verwendet man die Annotation @NodeEntity
auf Klassenebene. Die eindeutige Id eines Knoten wird mit @GraphId
annotiert. Die Vergabe dieser Ids übernimmt Neo4j transparent. Such-Indexe können mit der @Indexed
-Annotation definiert werden.
Ein Beziehung zwischen unseren Usern namens knows
(die ausdrücken soll, dass ein User U einen anderen User V kennt) definieren wir mit der Annotation @RelatedTo
an einem Set von Usern.
Das folgende Beispiel verwendet einen Graphen solcher User. Wir werden mit n
Usern arbeiten. Jeder User U_i
kennt alle anderen User U_j
(für alle 0 <= i < j <= n
). Ein User root
kennt alle anderen User. Für n = 3
kann der Graph wie folgt ausssehen:
Zur Visualisierung von Neo4j-Graphen kann auch eine RCP-Anwendung namens Neoclipse [6 ] verwendet werden-
Repository
Zur Definition eines Repositories mit allen CRUD-Operationen genügt bereits eine einzige Codezeile:
1public interface UserRepository extends GraphRepository<User> {}
Eigene Finder werden wir gleich hinzufügen. Nun werden wir erst mal einige User speichern mit der save()
-Methode:
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 );
Zur besseren Lesbarkeit haben wir eine Methode knows(...)
spendiert, die den übergebenen User der Menge der bekannten User hinzufügt. Kennt man die Id eines gespeicherten Knotens, kann man dessen Daten im Browser anzeigen lassen:
1http://localhost:7474/db/data/node/98
Um über das Spring Data API einzelne Knoten zu laden, kann der Standard-Finder findOne(long)
verwendet werden:
1User root = repo.findOne(rootId);
Nun ergänzen wir unser Repository um einige eigene Finder-Methoden:
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}
Die erste Query liefert einen einzelnen Knoten, dessen Property login
mit dem Suchkriterium übereinstimmt. Mit Hilfe der Annotation @Query
kann man auch frei definierbare Cypher [5 ] Queries schreiben. Dies übernimmt die zweite Query, die alle dem User root
bekannten User liefert.
Der komplette Quellcode des Beispiel kann unter github heruntergeladen werden.
Zusammenfassung
Das war’s für heute. Ich habe gezeigt, wie man einen Neo4j-Server installiert und startet. Wir haben ein Maven-basiertes Spring Data Neo4j-Projekt angelegt und konfiguriert. Nach dem Speichern eines eigenen Graphen haben wir eigene Finder geschrieben und auch direkt die Cypher Query Langugage verwwendet.
Das war natürlich nur ein kleiner Einblick ins Universum von Neo4j. Ich hoffe, es hat Euch gefallen. Für einen vertiefenden Einstieg empfehle ich die Neo4j-Homepage. Dort werden Themen wie eingebettete Datenbank mit Transaktionsunterstützung und Geodaten-Suchen beschrieben.
Das Spring Data Projekt
Dies sind meine andere Posts zum Thema Spring Data:
Teil 3: Spring Data Mongo DB
Teil 2: Spring Data JPA
Teil 1: Spring Data Commons
References
[1] Neo4j
[2] NoSQL databases
[3] Graphs
[4] Neo4j Download
[5] Cypher Cookbook
[6] Neoclipse Download
Weitere Beiträge
von Tobias Trelle
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
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.
Blog-Autor*in
Tobias Trelle
Software Architect
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.