Eine Anleitung zu Neo4J mit Java

1. Einleitung

In diesem Artikel geht es um Neo4j - eine der ausgereiftesten und umfassendsten Grafikdatenbanken auf dem heutigen Markt. Graphendatenbanken nähern sich der Aufgabe der Datenmodellierung mit der Ansicht, dass viele Dinge im Leben als Sammlung von Knoten (V) und Verbindungen zwischen ihnen dargestellt werden können, die als Kanten (E) bezeichnet werden.

2. Eingebettetes Neo4j

Der einfachste Weg, um mit Neo4j zu beginnen, ist die Verwendung der eingebetteten Version, in der Neo4j in derselben JVM wie Ihre Anwendung ausgeführt wird.

Zuerst müssen wir eine Maven-Abhängigkeit hinzufügen:

 org.neo4j neo4j 3.4.6 

Sie können diesen Link überprüfen, um die neueste Version herunterzuladen.

Als nächstes erstellen wir eine Fabrik:

GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory();

Schließlich erstellen wir eine eingebettete Datenbank:

GraphDatabaseService graphDb = graphDbFactory.newEmbeddedDatabase( new File("data/cars"));

Jetzt kann die eigentliche Aktion beginnen! Zuerst müssen wir einige Knoten in unserem Diagramm erstellen und dafür müssen wir eine Transaktion starten, da Neo4j jede destruktive Operation ablehnt, es sei denn, eine Transaktion wurde gestartet:

graphDb.beginTx();

Sobald eine Transaktion ausgeführt wird, können wir mit dem Hinzufügen von Knoten beginnen:

Node car = graphDb.createNode(Label.label("Car")); car.setProperty("make", "tesla"); car.setProperty("model", "model3"); Node owner = graphDb.createNode(Label.label("Person")); owner.setProperty("firstName", "baeldung"); owner.setProperty("lastName", "baeldung");

Hier haben wir einen Knoten Car mit den Eigenschaften make und model sowie den Knoten Person mit den Eigenschaften firstName und lastName hinzugefügt

Jetzt können wir eine Beziehung hinzufügen:

owner.createRelationshipTo(car, RelationshipType.withName("owner"));

Die obige Anweisung fügte eine Kante hinzu, die die beiden Knoten mit einer Eigentümerbezeichnung verbindet . Wir können diese Beziehung überprüfen, indem wir eine Abfrage ausführen, die in der leistungsstarken Cypher- Sprache von Neo4j geschrieben ist:

Result result = graphDb.execute( "MATCH (c:Car) <-[owner]- (p:Person) " + "WHERE c.make = 'tesla'" + "RETURN p.firstName, p.lastName");

Hier bitten wir Sie, einen Autobesitzer für jedes Auto zu finden, dessen Marke Tesla ist, und geben uns seinen Vor- und Nachnamen zurück. Es ist nicht überraschend, dass dies Folgendes zurückgibt: {p.firstName = baeldung, p.lastName = baeldung}

3. Cypher-Abfragesprache

Neo4j bietet eine sehr leistungsfähige und ziemlich intuitive Abfragesprache, die alle Funktionen unterstützt, die man von einer Datenbank erwarten würde. Lassen Sie uns untersuchen, wie wir diese Standardaufgaben zum Erstellen, Abrufen, Aktualisieren und Löschen ausführen können.

3.1. Knoten erstellen

Mit dem Schlüsselwort "Erstellen" können sowohl Knoten als auch Beziehungen erstellt werden.

CREATE (self:Company {name:"Baeldung"}) RETURN self

Hier haben wir ein Unternehmen mit einem einzigen Eigenschaft erstellt Namen . Eine Knotendefinition ist durch Klammern gekennzeichnet und ihre Eigenschaften sind in geschweiften Klammern eingeschlossen. In diesem Fall ist self ein Alias ​​für den Knoten und Company eine Knotenbezeichnung.

3.2. Beziehung erstellen

Es ist möglich, einen Knoten und eine Beziehung zu diesem Knoten in einer einzigen Abfrage zu erstellen:

Result result = graphDb.execute( "CREATE (baeldung:Company {name:\"Baeldung\"}) " + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "RETURN baeldung, tesla");

Hier haben wir Knoten baeldung und tesla erstellt und eine Eigentumsbeziehung zwischen ihnen hergestellt. Das Erstellen von Beziehungen zu bereits vorhandenen Knoten ist natürlich auch möglich.

3.3. Daten abrufen

Das Schlüsselwort MATCH wird verwendet, um Daten in Kombination mit RETURN zu finden und zu steuern, welche Datenpunkte zurückgegeben werden. Die WHERE- Klausel kann verwendet werden, um nur die Knoten herauszufiltern, die die gewünschten Eigenschaften haben.

Lassen Sie uns den Namen des Unternehmens herausfinden, das tesla modelX besitzt:

Result result = graphDb.execute( "MATCH (company:Company)-[:owns]-> (car:Car)" + "WHERE car.make='tesla' and car.model='modelX'" + "RETURN company.name");

3.4. Knoten aktualisieren

Das Schlüsselwort SET kann zum Aktualisieren von Knoteneigenschaften oder Beschriftungen verwendet werden. Fügen wir unserem Tesla Kilometer hinzu:

Result result = graphDb.execute("MATCH (car:Car)" + "WHERE car.make='tesla'" + " SET car.milage=120" + " SET car :Car:Electro" + " SET car.model=NULL" + " RETURN car");

Hier fügen wir eine neue Eigenschaft namens milage hinzu , ändern die Beschriftungen so, dass sie sowohl Auto als auch Elektro sind, und löschen schließlich die Modelleigenschaft insgesamt.

3.5. Knoten löschen

Das Schlüsselwort DELETE kann zum dauerhaften Entfernen von Knoten oder Beziehungen aus dem Diagramm verwendet werden:

graphDb.execute("MATCH (company:Company)" + " WHERE company.name='Baeldung'" + " DELETE company");

Hier haben wir eine Firma namens Baeldung gelöscht.

3.6. Parameterbindung

In den obigen Beispielen haben wir fest codierte Parameterwerte, was nicht die beste Vorgehensweise ist. Glücklicherweise bietet Neo4j eine Möglichkeit, Variablen an eine Abfrage zu binden:

Map params = new HashMap(); params.put("name", "baeldung"); params.put("make", "tesla"); params.put("model", "modelS"); Result result = graphDb.execute("CREATE (baeldung:Company {name:$name}) " + "-[:owns]-> (tesla:Car {make: $make, model: $model})" + "RETURN baeldung, tesla", params);

4. Java-Treiber

Bisher haben wir uns mit der Interaktion mit einer eingebetteten Neo4j- Instanz befasst. Höchstwahrscheinlich möchten wir jedoch einen eigenständigen Server ausführen und über einen bereitgestellten Treiber eine Verbindung zu ihm herstellen. Zuerst müssen wir eine weitere Abhängigkeit in unsere maven pom.xml einfügen :

 org.neo4j.driver neo4j-java-driver 1.6.2 

Sie können diesem Link folgen, um nach der neuesten Version dieses Treibers zu suchen.

Jetzt können wir eine Verbindung herstellen:

Driver driver = GraphDatabase.driver( "bolt://localhost:7687", AuthTokens.basic("neo4j", "12345"));

Erstellen Sie dann eine Sitzung:

Session session = driver.session();

Schließlich können wir einige Abfragen ausführen:

session.run("CREATE (baeldung:Company {name:\"Baeldung\"}) " + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "RETURN baeldung, tesla");

Sobald wir mit all unserer Arbeit fertig sind, müssen wir sowohl die Sitzung als auch den Fahrer schließen:

session.close(); driver.close();

5. JDBC-Treiber

It is also possible to interact with Neo4j via a JDBC driver. Yet another dependency for our pom.xml:

 org.neo4j neo4j-jdbc-driver 3.4.0 

You can follow this link to download the latest version of this driver.

Next, let's establish a JDBC connection:

Connection con = DriverManager.getConnection( "jdbc:neo4j:bolt://localhost/?user=neo4j,password=12345,scheme=basic");

Here con is a regular JDBC connection which can be used for creating and executing statements or prepared statements:

try (Statement stmt = con. stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "RETURN baeldung, tesla") ResultSet rs = stmt.executeQuery( "MATCH (company:Company)-[:owns]-> (car:Car)" + "WHERE car.make='tesla' and car.model='modelX'" + "RETURN company.name"); while (rs.next()) { rs.getString("company.name"); } }

6. Object-Graph-Mapping

Object-Graph-Mapping or OGM is a technique which enables us to use our domain POJOs as entities in the Neo4j database. Let us examine how this works. The first step, as usually, we add new dependencies to our pom.xml:

 org.neo4j neo4j-ogm-core 3.1.2   org.neo4j neo4j-ogm-embedded-driver 3.1.2 

You can check the OGM Core Link and OGM Embedded Driver Link to check for the latest versions of these libraries.

Second, we annotate our POJO's with OGM annotations:

@NodeEntity public class Company { private Long id; private String name; @Relationship(type="owns") private Car car; } @NodeEntity public class Car { private Long id; private String make; @Relationship(direction = "INCOMING") private Company company; }

@NodeEntity informs Neo4j that this object will need to be represented by a node in the resulting graph. @Relationship communicates the need to create a relationship with a node representing the related type. In this case, a company owns a car.

Please note that Neo4j requires each entity to have a primary key, with a field named id being picked up by default. An alternatively named field could be used by annotating it with @Id @GeneratedValue.

Then, we need to create a configuration that will be used to bootstrap Neo4j‘s OGM. For simplicity, let us use an embedded in-memory only database:

Configuration conf = new Configuration.Builder().build();

After that, we initialize SessionFactory with the configuration we created and a package name in which our annotated POJO's reside:

SessionFactory factory = new SessionFactory(conf, "com.baeldung.graph");

Finally, we can create a Session and begin using it:

Session session = factory.openSession(); Car tesla = new Car("tesla", "modelS"); Company baeldung = new Company("baeldung"); baeldung.setCar(tesla); session.save(baeldung);

Here we initiated a session, created our POJO's and asked OGM session to persist them. Neo4j OGM runtime transparently converted objects to a set of Cypher queries which created appropriate nodes and edges in the database.

If this process seems familiar, that is because it is! That is precisely how JPA works, the only difference being whether object gets translated into rows that are persisted to an RDBMS, or a series of nodes and edges persisted to a graph database.

7. Conclusion

Dieser Artikel befasste sich mit einigen Grundlagen einer graphorientierten Datenbank Neo4j.

Wie immer ist der Code in dieser Beschreibung überall auf Github verfügbar.