Connecting to Neo4j

As you start interacting with Neo4j, you must call the query() method on a Neo4jGraph instance. It is best practice to create a single instance of the Neo4jGraph class for use across the application.

In this challenge, you must create an instance using the environment variables added to the .env.local file in the previous module.

Open src/modules/graph.ts

Create a Neo4jGraph instance

The src/modules/graph.ts file already has a placeholder function that the application uses to create or return a singleton instance of Neo4jGraph.

In src/modules/graph.ts, find the initGraph() function.

typescript
// <1> The singleton instance
let graph: Neo4jGraph;

/**
 * <2> Return the existing `graph` object or create one
 * has not already been created
 * @returns {Promise<Neo4jGraph>}
 */
export async function initGraph(): Promise<Neo4jGraph> {
  if (!graph) {
    // TODO: Create singleton and wait for connection to be verified
  }

  return graph;
}

The code (1) defines a variable for storing the Neo4jGraph and (2) implements a function to either return an existing Neo4jGraph object or create a new one if it doesn’t exist, employing the singleton pattern.

Inside the if statement, call the Neo4jGraph.initialize() method, passing the url, username, and password defined in the environment variables.

typescript
Create the Neo4j Graph instance
if (!graph) {
  // Create singleton and wait for connection to be verified
  graph = await Neo4jGraph.initialize({
    url: process.env.NEO4J_URI as string,
    username: process.env.NEO4J_USERNAME as string,
    password: process.env.NEO4J_PASSWORD as string,
    database: process.env.NEO4J_DATABASE as string | undefined,
  });
}

The Neo4jGraph.initialize() method will create a new Neo4jGraph instance and verify connectivity to the database. Verifying connectivity ensures that the Neo4j credentials are correct and throws an error if the application cannot establish a connection.

typescript
Return the singleton
return graph;

If you have followed the instructions correctly, your initGraph function should resemble the following:

typescript
initGraph
// <1> The singleton instance
let graph: Neo4jGraph;

/**
 * Return the existing `graph` object or create one
 * has not already been created
 *
 * @returns {Promise<Neo4jGraph>}
 */
export async function initGraph(): Promise<Neo4jGraph> {
  if (!graph) {
    // Create singleton and wait for connection to be verified
    graph = await Neo4jGraph.initialize({
      url: process.env.NEO4J_URI as string,
      username: process.env.NEO4J_USERNAME as string,
      password: process.env.NEO4J_PASSWORD as string,
      database: process.env.NEO4J_DATABASE as string | undefined,
    });
  }

  return graph;
}

Testing your changes

If you have followed the instructions, you should be able to run the following unit test to verify the response using the npm run test command.

sh
Running the Test
npm run test graph.test.ts
View Unit Test
typescript
graph.test.ts
import { initGraph } from "./graph";
import { Neo4jGraph } from "@langchain/community/graphs/neo4j_graph";

describe("Neo4j Graph", () => {
  it("should have environment variables defined", () => {
    expect(process.env.NEO4J_URI).toBeDefined();
    expect(process.env.NEO4J_USERNAME).toBeDefined();
    expect(process.env.NEO4J_PASSWORD).toBeDefined();
  });

  describe("initGraph", () => {
    it("should instantiate Neo4jGraph", async () => {
      const graph = await initGraph();

      expect(graph).toBeInstanceOf(Neo4jGraph);

      await graph.query("MERGE (t:DriverTest {working: true})");

      await graph.close();
    });
  });
});

Verifying the Test

If every test in the test suite has succeeded, a (:DriverTest) node will be created in your database.

Click the Check Database button below to verify the tests have succeeded.

Hint

You can compare your code with the solution in src/solutions/modules/graph.ts and double-check that the conditions have been met in the test suite.

Solution

You can compare your code with the solution in src/solutions/modules/graph.ts and double-check that the conditions have been met in the test suite.

You can also run the following Cypher statement to double-check that the index has been created in your database.

cypher
MATCH (t:DriverTest {working: true})
RETURN count(*)

Once you have verified your code and re-ran the tests, click Try again…​* to complete the challenge.

Summary

In this lesson, you created a singleton Neo4jGraph object that you will use across the application.

In the next lesson, you will use this object to save and retrieve conversation history.