Using an Application for Import

About this module

You have just learned how to import data into the graph using the import tool of neo4j-admin. Another way that you can import data into the graph is with an application that connects to the database instance using one of the supported drivers. In a java-based application, you can import data by establishing a connection to both the relational database and the Neo4j database to read from the relational database via jdbc drivers and access the Neo4j database using the appropriate language drivers. Next, you will learn about the Neo4j drivers to load data into the graph.

At the end of this module, you will be able to:

  • Read data from a relational database and create nodes in a Neo4j database using the Neo4j Java drivers.

Why use an application for the import?

If you are planning on using data from a relational database to create nodes and relationships in a graph, you may want to consider using one of the supported Neo4j language drivers to help you. Writing the application to perform the import gives you more fine-grained control of the process.

Recall that the supported drivers for Neo4j includes:

  • Java

  • JavaScript

  • Python

  • C#

  • Go

Application control using drivers

With an application that uses these drivers, you can control:

  • What node and relationship updates can be in a transaction.

  • How large a transaction will be (batching).

  • How much concurrent processing you want to implement (parallel processing).

You can read more about specific drivers in the Developer pages for Neo4j Drivers.

Synchronous or asynchronous access?

From the drivers that Neo4j supports, you must decide whether you will make calls to the Neo4j database that must wait for the server. The programming model you choose will depend upon the concurrency requirements for the import process. Some drivers support concurrency while others do not.

Example: Synchronous Java example

Here is an example where we wait for the call to return before continuing:

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

try (Session session = driver.session()) {
    session.readTransaction((tx) -> {
        StatementResult result = tx.run("MATCH (a:Person) RETURN a.name");
        while (result.hasNext()) {
            Record record = result.next();
            System.out.println(record.get("a.name"));
        }
    });
}

Example: Asynchronous Java example

Here is an example where we continue processing while the call executes:

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

Session session = driver.session();
session.readTransactionAsync(tx ->
    tx.runAsync("MATCH (a:Country) RETURN a.name").thenCompose(cursor ->
        cursor.forEachAsync(System.out::println)
    )
).whenComplete((ignore, error) -> session.closeAsync());

Example: Synchronous Python example

uri = "bolt://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("neo4j", "p4ssw0rd"))

def print_names(tx):
    result = tx.run("MATCH (a:Person) RETURN a.name")
    for record in result:
        print(record["a.name"])

with driver.session() as session:
    session.read_transaction(print_names)

Example: Synchronous JavaScript example

const neo4j = require('neo4j-driver').v1;
const uri = 'bolt://localhost:7687';
const driver = neo4j.driver(uri, neo4j.auth.basic('neo4j', 'p4ssw0rd'));

const session = driver.session();
const resultPromise = session.readTransaction(tx =>
    tx.run('MATCH (a:Person) RETURN a.name')
);
resultPromise.then(result => {
    result.records.forEach(record => console.log(record));
    session.close();
});

Example: Synchronous C# example

var uri = "bolt://localhost:7687";
var driver = GraphDatabase.Driver(uri, AuthTokens.Basic("neo4j", "p4ssw0rd"));

using (var session = driver.Session()) {
session.ReadTransaction(tx => {
     	var result = tx.Run("MATCH (a:Person) RETURN a.name");
foreach (var record in result) {
Console.WriteLine(record["a.name"]);
}
});
}

Example: Asynchronous C# example

var uri = "bolt://localhost:7687";
var driver = GraphDatabase.Driver(uri, AuthTokens.Basic("neo4j", "p4ssw0rd"));

var session = driver.Session();
try {
    await session.ReadTransactionAsync(async tx => {
      var result = await tx.RunAsync("MATCH (a:Country) RETURN a.name");
      while (await result.FetchAsync()) {
          Console.WriteLine(result.Current[0].As<string>());
      }
  });
}
finally {
  await session.CloseAsync();
}

Example: Importing data from RDBMS to Neo4j

Here is a very simple example that shows the Java code for retrieving data from an RDBMS and using it to create nodes in the graph:

rdbms2graph.groovy

@GrabConfig( systemClassLoader=true )
@Grapes([
  @Grab(group='org.postgresql', module='postgresql', version='42.0.0'),
  @Grab(group='org.neo4j.driver', module='neo4j-java-driver', version='4.0.0')
])

import org.neo4j.driver.*;
import java.sql.*;
Class.forName("org.postgresql.Driver");

table = "products";
JDBC = [url:"jdbc:postgresql://db-examples.cmlvojdj5cci.us-east-1.rds.amazonaws.com/northwind", user:"n4examples", pass:"36gdOVABr3Ex"];
NEO4J=[url:"bolt://localhost:7687", user:"neo4j",pass:"training-helps"];

// see https://neo4j.com/docs/api/java-driver/current/
GraphDatabase.driver(NEO4J.url, AuthTokens.basic(NEO4J.user,
                     NEO4J.pass)).withCloseable{ neo4j ->
                     DriverManager.getConnection(JDBC.url,
                            JDBC.user, JDBC.pass).withCloseable
                            { rdbms ->
                     stmt = rdbms.prepareStatement("SELECT * FROM ${table}");

neo4j.session(
      SessionConfig.builder().withDatabase("products").build()).withCloseable{
      session -> session.writeTransaction { tx ->
   stmt.executeQuery().withCloseable{ rs ->
     meta = rs.getMetaData();
     cols = meta.getColumnCount();
     while (rs.next()) {
        params = [:];
        for (int i=0;i<cols;i++) {
           params[meta.getColumnName(i+1)]=rs.getObject(i+1);
        }
        println(params);
        tx.run("CREATE (n:${table}) SET n += \$props",
               Values.value([props:params])).consume();
     }
   }
}}}}

This code uses a synchronous programming model to create each node in the graph.

Exercise: Importing data from an RDBMS using an application

In the query edit pane of Neo4j Browser, execute the browser command:

:play 4.0-intro-neo4j-exercises

and follow the instructions for Exercise 19.

This exercise has 5 steps. Estimated time to complete: 10 minutes.

Check your understanding

Question 1

What supported drivers can you use to write a Neo4j application?

Select the correct answers.

  • Java

  • JavaScript

  • Python

  • Go

  • C#

Question 2

What programming languages support asynchronous calls to Neo4j:

Select the correct answers.

  • JavaScript

  • Java

  • Python

  • C#

Question 3

What programming languages support synchronous calls to Neo4j:

Select the correct answers.

  • JavaScript

  • Java

  • Python

  • C#

Summary

You can now:

  • Read data from a relational database and create nodes in a Neo4j database using the Neo4j Java drivers.