In the Cypher Fundamentals course, we cover how to query Neo4j using a language called Cypher. To execute a Cypher statement against a Neo4j database you will use an object called a Driver.
To connect to and query Neo4j from within a Go application, you use the Neo4j Go Driver.
Installing the Driver
The Neo4j Go Driver is available through pkg.go.dev.
The Neo4j Go Driver can be installed using the go get
command.
go get -u github.com/neo4j/neo4j-go-driver/v5
Importing the Library
The github.com/neo4j/neo4j-go-driver
package exports a neo4j
object which contains several helper functions for interacting with Neo4j.
// Import the driver
import (
"context"
"fmt"
"time"
. "github.com/neo4j-graphacademy/neoflix/pkg/shared"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
)
Creating a Driver Instance
To create a new instance of the driver, you can use the neo4j.NewDriverWithContext()
function provided by the driver library, which accepts neo4j credentials and returns a new driver object.
// Create a Driver Instance
ctx := context.Background()
driver, err := neo4j.NewDriverWithContext(
"neo4j+s://dbhash.databases.neo4j.io", // (1)
neo4j.BasicAuth("neo4j", "letmein!", ""), // (2)
)
The function expects two arguments;
-
A Connection URI - for example,
neo4j://localhost:7687
orneo4j+s://dbhash.databases.neo4j.io
-
An authentication token
Authentication Types
Neo4j supports four authentication methods, basic authentication (e.g. username and password or LDAP), a base64 encoded Bearer token, a Kerberos token, or a custom authentication token. For more information on these options, visit Authentication and Authorization.
Verifying Connectivity
You can verify that the connection details used during driver instantiation are correct by calling the driver.VerifyConnectivity()
method.
This function returns an error with the Neo.ClientError.Security.Unauthorized
code if the provided credentials are incorrect.
// Verify Connectivity
PanicOnErr(driver.VerifyConnectivity(ctx))
Sessions
From the driver object, you will open one or more sessions. A session is a client-side abstraction that borrows underlying TCP connections from a connection pool held by the Driver and uses them to communicate with Neo4j.
Sessions should be considered lightweight and disposable and can be opened and closed at will.
To close a session, call the .Close()
method.
This will release any underlying TCP connections held by the session object.
// Open a new Session
session := driver.NewSession(ctx, neo4j.SessionConfig{})
You can implicitly defer
the closing of each session object, which will release any underlying TCP connections held by the session object once the surrounding context has completed.
defer PanicOnClosureError(ctx, driver)
defer PanicOnClosureError(ctx, session)
Running a Sample Query
To run a one-off Cypher query, you can use the session.Run()
method.
// Execute a Cypher statement in an auto-commit transaction
result, err := session.Run(
ctx, // (1)
`
MATCH (p:Person)-[:DIRECTED]->(:Movie {title: $title})
RETURN p
`, // (2)
map[string]any{"title": "The Matrix"}, // (3)
func(txConfig *neo4j.TransactionConfig) {
txConfig.Timeout = 3 * time.Second // (4)
},
)
PanicOnErr(err)
The method accepts four arguments:
-
The execution context.
-
A string to represent a Cypher statement
-
An optional map representing query parameters (prefixed in Cypher with
$
). -
Optional, a map containing transaction config.
For one-off queries only
If there are any transient errors when running a query, the driver will not attempt to retry a query when usingsession.Run()
.
For this reason, these should only be used for one-off queries and not in production.Processing Results
The result
value in the code sample above will be an implementation of the ResultWithContext
interface.
This can be used in conjunction with the neo4j.CollectTWithContext()
function to access the values returned by Neo4j.
The function expects a context object, a ResultWithContext
object, and an accessor function.
The function is passed one argument, an instance of neo4j.Record
, which can be passed to the neo4j.GetRecordValue()
method.
// Get all Person nodes
people, err := neo4j.CollectTWithContext[neo4j.Node](ctx, result,
func(record *neo4j.Record) (neo4j.Node, error) {
person, _, err := neo4j.GetRecordValue[neo4j.Node](record, "p")
return person, err
})
PanicOnErr(err)
fmt.Println(people)
In the code sample above, the p
value is extracted from each node using the neo4j.GetRecordValue()
function, which is assigned to the person
variable.
In this instance, p
refers to a Neo4j Node, which is hydrated into an instance of the neo4j.Node
interface.
Should the p
key not exist on the record or any other error occurs while trying to retrieve the value, the subsequent error will be assigned to the err
variable.
We will cover result processing in more detail in Lesson 3: Read and Write Transactions.
Closing the Driver
The Driver provides a .Close()
method, which closes any open sessions, disconnect all servers and release any resources held by the driver.
// Close the driver to release any resources
driver.Close(ctx)
Check Your Understanding
What symbol do you need to import to use the Neo4j Go Driver?
-
❏
neo4j
-
❏
go.dev/neo4j/driver
-
✓
github.com/neo4j/neo4j-go-driver/v5/neo4j
-
❏
neo4j-go-driver
Hint
You can search for the package on pkg.go.dev.
Solution
The symbol you need to import is github.com/neo4j/neo4j-go-driver/v5/neo4j
.
Summary
In this lesson, you learned the basics of the Neo4j Go Driver, how to install the dependency, create a new driver instance and execute a sample query.
In the next lesson, you will use this knowledge to query a Neo4j Sandbox instance.