Der erste Artikel in der Reihe über NoSQL hat sich sehr allgemein mit dem Thema auseinandergesetzt. Dieser zweite Teil wird die Thematik etwas genauer beleuchten und anhand derGraphdatenbank “Neo4j” vertiefen.

igcjeafc

Neo4j definiert sich, aus dem englischen übersetzt wie folgt:

Neo4j ist eine robuste (ACID - fähige), transaktionale, eigenschaftsbasierte Graphdatenbank. Neo4j ist durch sein Graphdatenmod
ell hochagil und extrem schnell. Bei verknüpften Abfragen ist Neo4j tausendfach performanter als relationale Datenbanken.

Ziel dieses Artikels ist es Neo4j herunterzuladen, zu starten und Daten über die mitgelieferte Neo4j-Shell einzufügen und abzufragen.

Neo4j wird auf http://www.neo4j.org/install zum Download angeboten. Auf dieser Seite können drei unterschiedliche Versionen heruntergeladen werden. Neo4j wird in den Varianten - “Community”, “Advanced” und “Enterprise” - angeboten. Das Modell entspricht dem anderer bekannter RDBMS-Anbieter, nur die Community-Variante ist umsonst, für die anderen Versionen fallen Kosten an.

Nach dem Herunterladen baut sich das entpackte Archiv wie folgt auf:

hbo: ~/Downloads/neo4j-community-1.8.1 > ls
total 464
drwxr-xr-x@ 17 hbo staff 578 13 Feb 15:15 .
drwx------+ 389 hbo staff 13226 13 Feb 13:52 ..
-rw-r--r--@ 1 hbo staff 6148 13 Feb 14:07 .DS_Store
-rw-r--r-- 1 hbo staff 162 13 Feb 15:31 .shell_history
-rw-r--r--@ 1 hbo staff 31710 13 Dez 18:22 CHANGES.txt
-rw-r--r--@ 1 hbo staff 36045 13 Dez 18:22 LICENSE.txt
-rw-r--r--@ 1 hbo staff 133593 13 Dez 18:22 LICENSES.txt
-rw-r--r--@ 1 hbo staff 5370 13 Dez 18:22 NOTICE.txt
-rw-r--r--@ 1 hbo staff 1946 13 Dez 18:22 README.txt
-rw-r--r--@ 1 hbo staff 5853 13 Dez 18:22 UPGRADE.txt
drwxr-xr-x@ 9 hbo staff 306 13 Dez 18:22 bin
drwxr-xr-x@ 10 hbo staff 340 13 Feb 15:12 conf
drwxr-xr-x@ 8 hbo staff 272 13 Feb 15:12 data
drwxr-xr-x@ 9 hbo staff 306 13 Dez 18:22 doc
drwxr-xr-x@ 16 hbo staff 544 13 Dez 18:22 lib
drwxr-xr-x@ 3 hbo staff 102 13 Dez 18:22 plugins
drwxr-xr-x@ 4 hbo staff 136 13 Dez 18:22 system

Starten des Neo4j-Servers:

hbo: ~/Downloads/neo4j-community-1.8.1 > ./bin/neo4j start

Erfolgreich gestartet:

hbo: ~/Downloads/neo4j-community-1.8.1 > ./bin/neo4j start
Starting Neo4j Server...16:11:22,219 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
snip …
… snap
process [9057]... waiting for server to be ready...... OK.
Go to http://localhost:7474/webadmin/ for administration interface.

Neo4j ist nun über eine Weboberfläche (siehe letzte Zeile des Startvorgangs) erreichbar und administrierbar. Nach Eingabe der URL http://localhost:7474/webadmin/ zeigt sich die Startseite der Administrationsoberfläche wie folgt:

Neo4j Webadmin 640

Als Ausgangspunkt wird das Dashboard angezeigt. Über dieses lassen sich einige Eckdaten des Graphens ablesen, wie Gesamtanzahl der enthaltenen Knoten oder auch eine graphische Darstellung über die zeitliche Veränderung von Knoten, Kanten und deren Eigenschaften. Da der Graph das erste mal gestartet wurde ist er noch leer - Lediglich ein Knoten, der Wurzelknoten ist enthalten. Dieser Artikel wird nicht auf die weiteren Funktionen der Administration eingehen, sondern nur den “Databrowser” verwenden, um die per Konsole eingefügten Daten zu visualisieren.

Starten der Neo4j-Shell:

hbo: ~/Downloads/neo4j-community-1.8.1 > ./bin/neo4j-shell
	Welcome to the Neo4j Shell! Enter 'help' for a list of commands
	NOTE: Remote Neo4j graph database service 'shell' at port 1337
	neo4j-sh (0)$

Ab jetzt können alle Befehle, die über ‘help’ erreichbar sind eingegeben werden.

neo4j-sh (0)$ help
Available commands: alias begin cd commit create cypher dbinfo env eval export gsh help index jsh ls man mknode mkrel mv paths pwd rm rmnode rmrel rollback set start trav
Use man <command></command> for info about each command.
<command></command> neo4j-sh (0)$

Für die Beispieldaten wird folgendes fiktive ;-) Szenario verwendet:

“Eine Facebook-App der ‘NoSql Bar’ hat Zugriff auf die Daten des Benutzers unter anderem auf die seiner Freunde. Das Ziel ist es, per Facebook Werbung an den Benutzer der App zu verschicken und dessen Freunde von einem Konkurrenten abzuwerben. Hierzu soll jeden Freitag und Samstag Abend folgende Menge ermittelt werden. “Der Benutzer der App selber, zusätzlich alle Freunde des Benutzers die Anhänger des Konkurrenten “Relational Bar” sind und sich gerade in München befinden.”

Bevor die Abfrage formuliert wird, müssen alle Knoten angelegt werden. Wie in Teil 1 der “NoSQL”-Reihe bereits als Vorteil von NoSQL erwähnt, werden die Daten schemalos gespeichert werden. Dies geschieht zum einen über Knoten und zum anderen über Relationen (Kanten) um die Knoten zu verbinden. Beide Typen, Knoten und Kanten können wiederum Eigenschaften als Key-Value-Pairs besitzen. Damit ergibt sich für unser Szenario folgende, sehr gut lesbare und UML-freie Darstellung des Datenmodells:

data modell

Um die Daten in Graph einzufügen werden über die Neo4-Shell zunächst alle Knoten angelegt, dann die Relationen zwischen den Knoten. Dies geschieht über die Befehle “mknode” und “mkrel”

Bars anlegen:

neo4j-sh (0)$ mknode -v --np "{'name':'NoSql Bar'}"
Node (NoSql Bar,1) created
neo4j-sh (0)$ mknode -v --np "{'name':'Relational Bar'}"
Node (Relational Bar,2) created

Orte anlegen:

neo4j-sh (0)$ mknode -v --np "{'city':'Munich'}"
Node (3) created
neo4j-sh (0)$ mknode -v --np "{'city':'Berlin'}"
Node (4) created

Personen anlegen:

neo4j-sh (0)$ mknode -v --np "{'firstname':'Seth'}"
Node (Seth,5) created
neo4j-sh (0)$ mknode -v --np "{'firstname':'Richard'}"
Node (Richard,6) created
neo4j-sh (0)$ mknode -v --np "{'firstname':'Jacob'}"
Node (Jacob,7) created
neo4j-sh (0)$ mknode -v --np "{'firstname':'Kate'}"
Node (Kate,8) created

Kanten zwischen Personen und Orten

neo4j-sh (0)$ cd -a 5
neo4j-sh (Seth,5)$ mkrel -t IS_LOCATED_AT 3
neo4j-sh (Seth,5)$ cd -a 6
neo4j-sh (Richard,6)$ mkrel -t IS_LOCATED_AT 3
neo4j-sh (Richard,6)$ cd -a 7
neo4j-sh (Jacob,7)$ mkrel -t IS_LOCATED_AT 3
neo4j-sh (Jacob,7)$ cd -a 8
neo4j-sh (Kate,8)$ mkrel -t IS_LOCATED_AT 4

Kanten zwischen Personen

neo4j-sh (Kate,8)$ cd -a 5
neo4j-sh (Seth,5)$ mkrel -t IS_FRIEND_OF 6
neo4j-sh (Seth,5)$ mkrel -t IS_FRIEND_OF 7
neo4j-sh (Seth,5)$ mkrel -t IS_FRIEND_OF 8

Kanten zwischen Personen und Bars

neo4j-sh (Seth,5)$ mkrel -t LIKES 1
neo4j-sh (Seth,5)$ cd -a 6
neo4j-sh (Richard,6)$ mkrel -t LIKES 2
neo4j-sh (Richard,6)$ cd -a 7
neo4j-sh (Jacob,7)$ mkrel -t LIKES 2
neo4j-sh (Jacob,7)$ cd -a 8
neo4j-sh (Kate,8)$ mkrel -t LIKES 1
neo4j-sh (Kate,8)$ mkrel -t LIKES 2

Kanten zwischen Bars und Orten

neo4j-sh (Kate,8)$ cd -a 1
neo4j-sh (NoSql Bar,1)$ mkrel -t IS_LOCATED_AT 3
neo4j-sh (NoSql Bar,1)$ cd -a 2
neo4j-sh (Relational Bar,2)$ mkrel -t IS_LOCATED_AT 3

Nachdem alle Knoten und Kanten angelegt sind, kann das Ergebnis in der Administrationsoberfläche von Neo4j unter http://localhost:7474/webadmin überprüft werden. Hierzu muss nur die ID von “Seth”, die “5” in den Databrowser eingegeben werden.

Nach einem Klick auf den folgenden Button kann durch den gesamten Graph navigiert. Nach einem Klick auf die einen Knoten werden automatisch alle weiteren verbundenen Knoten angezeigt, bis der gesamte Graph zu sehen.

show graph
Um nun die Menge der Benutzer aus dem Test-Szenario zu ermitteln, muss eine sog. Cypher-Query formuliert werden. Hierbei handelt es sich um das Pendant zu SQL. Dies sieht in unserem Fall auf der Neo4j-Shell wie folgt aus

neo4j-sh (0)$ cypher 1.8
> START seth=node(5)
>
> MATCH seth-[:IS_FRIEND_OF]-friendOfSeth,
> friendOfSeth-[:LIKES]-someBar,
> friendOfSeth-[:IS_LOCATED_AT]-someCity
>
> WHERE someBar.name = "Relational Bar"
> AND someCity.city = "Munich"
>
> RETURN friendOfSeth.firstname;
+------------------------+
| friendOfSeth.firstname |
+------------------------+
| "Richard" |
| "Jacob" |
+------------------------+
2 rows
3 ms

START - legt den Anfangsknoten der Traversierung fest
MATCH - legt alle zu durchlaufenden Relationen fest
WHERE - schränkt die Menge der zu durchlaufenden Knoten ein
RETURN - gibt die Ergebnisse zurück

Damit werden Richard und Jacob als abzuwerbende Personen gefunden jedoch nicht Kate, da sie sich gerade in Berlin befindet.

Dieser Artikel hat die Verwendung von Neo4j in der mitgelieferten Shell gezeigt. Das Beispiel soll einen Anwendungsfall zeigen der eine NoSQL Datenbank auch für Unternehmen mit kleineren Datenbeständen interessant macht. Überträgt man das Szenario und die darin enthaltenen Daten auf diesen Vergleich so wird schnell klar wie sich die Performance zwischen RDBMS und NoSQL-Systemen verhält.

Das Team der Scandio GmbH hat Projekterfahrung in den Bereichen JackRabbit und neo4j. In den folgenden Artikeln zum Thema NoSQL werden einige technische Beispiele zu neo4j gezeigt.

Weblinks

http://www.neo4j.org/
http://docs.neo4j.org/chunked/stable/shell.html
http://architects.dzone.com/articles/performance-graph-vs

Firmenportrait:
Die Scandio GmbH ist ein IT-Beratungs- und Softwareunternehmen aus München. Wir entwickeln individuelle Web-Applikationen für Ihr Unternehmen. Zu unseren Stärken gehören Web Content Management Systeme, Suchmaschinen-Technologie (Lucene, Apache Solr), Datenbank- und eCommerce-Systeme und alle Mischformen daraus. Mehr über unsere Leistungen erfahren Sie in unserem Portfolio.