Un guide de Neo4J avec Java

1. Introduction

Cet article concerne Neo4j - l'une des bases de données graphiques les plus matures et les plus complètes du marché aujourd'hui. Les bases de données de graphes abordent la tâche de modélisation des données avec l'idée que beaucoup de choses dans la vie se prêtent à être représentées comme un ensemble de nœuds (V) et de connexions entre eux appelés arêtes (E).

2. Neo4j intégré

Le moyen le plus simple de démarrer avec Neo4j est d'utiliser la version intégrée dans laquelle Neo4j s'exécute dans la même JVM que votre application.

Tout d'abord, nous devons ajouter une dépendance Maven:

 org.neo4j neo4j 3.4.6 

Vous pouvez consulter ce lien pour télécharger la dernière version.

Ensuite, créons une usine:

GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory();

Enfin, nous créons une base de données embarquée:

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

Maintenant, la vraie action peut commencer! Tout d'abord, nous devons créer des nœuds dans notre graphe et pour cela, nous devons démarrer une transaction car Neo4j rejettera toute opération destructive à moins qu'une transaction n'ait été lancée:

graphDb.beginTx();

Une fois que nous avons une transaction en cours, nous pouvons commencer à ajouter des nœuds:

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");

Ici, nous avons ajouté un nœud Car avec les propriétés make et model ainsi que le nœud Person avec les propriétés firstName et lastName

Maintenant, nous pouvons ajouter une relation:

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

La déclaration ci-dessus a ajouté une arête joignant les deux nœuds avec une étiquette de propriétaire . Nous pouvons vérifier cette relation en exécutant une requête écrite dans le puissant langage Cypher de Neo4j :

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

Ici, nous demandons de trouver un propriétaire de voiture pour toute voiture dont la marque est tesla et de nous rendre son prénom et son nom. Sans surprise, cela renvoie: {p.firstName = baeldung, p.lastName = baeldung}

3. Langage de requête de chiffrement

Neo4j fournit un langage d'interrogation très puissant et assez intuitif qui prend en charge la gamme complète des fonctionnalités attendues d'une base de données. Examinons comment nous pouvons accomplir ces tâches standard de création, de récupération, de mise à jour et de suppression.

3.1. Créer un nœud

Le mot clé Create peut être utilisé pour créer à la fois des nœuds et des relations.

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

Ici, nous avons créé une entreprise avec un seul nom de propriété . Une définition de nœud est marquée par des parenthèses et ses propriétés sont placées entre accolades. Dans ce cas, self est un alias pour le nœud et Company est une étiquette de nœud.

3.2. Créer une relation

Il est possible de créer un nœud et une relation avec ce nœud en une seule requête:

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

Ici, nous avons créé des nœuds baeldung et tesla et établi une relation de propriété entre eux. La création de relations avec des nœuds préexistants est bien entendu également possible.

3.3. Récupérer des données

Le mot clé MATCH est utilisé pour rechercher des données en combinaison avec RETURN pour contrôler les points de données renvoyés. La clause WHERE peut être utilisée pour filtrer uniquement les nœuds qui ont les propriétés souhaitées.

Découvrons le nom de l'entreprise propriétaire de tesla modelX:

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

3.4. Mettre à jour les nœuds

Le mot clé SET peut être utilisé pour mettre à jour les propriétés ou les étiquettes des nœuds. Ajoutons le kilométrage à notre tesla:

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");

Ici, nous ajoutons une nouvelle propriété appelée kilométrage , modifions les étiquettes pour qu'elles soient à la fois Car et Electro et enfin, nous supprimons complètement la propriété du modèle .

3.5. Supprimer les nœuds

Le mot clé DELETE peut être utilisé pour la suppression permanente des nœuds ou des relations du graphique:

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

Ici, nous avons supprimé une société nommée Baeldung.

3.6. Parameter Binding

In the above examples, we have hard-coded parameter values which isn't the best practice. Luckily, Neo4j provides a facility for binding variables to a query:

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 Driver

So far we've been looking at interacting with an embedded Neo4j instance, however, in all probability for production, we'd want to run a stand-alone server and connect to it via a provided driver. First, we need to add another dependency in our maven pom.xml:

 org.neo4j.driver neo4j-java-driver 1.6.2 

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

Now we can establish a connection:

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

Then, create a session:

Session session = driver.session();

Finally, we can run some queries:

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

Once we are done with all our work we need to close both session and the driver:

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

5. JDBC Driver

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

Cet article a examiné quelques bases d'une base de données orientée graphes Neo4j.

Comme toujours, le code de cet article est disponible sur Github.