In the last challenge, you used session.Run()
to execute a Cypher statement in an auto-complete transaction.
While that may be convenient for one-off statements but is not suitable for production applications.
When using Neo4j in a clustered environment, the server will not attempt to retry the query when using session.Run()
.
In the case of transient errors, for example, changes to the cluster topology, Cypher statements explicitly executed within a read or write transaction will be retried in an attempt to cause minimal disruption to your application.
Neo4j Clusters
When running Neo4j in production or using Neo4j Aura, you will most likely be querying a cluster of nodes rather than a single instance.
Neo4j clusters consist of a set of core nodes responsible for reaching consensus when writing data to a database. Additional read-only servers called Read Replicas can be added to increase the possible number of simultaneous read queries at any time.
In a clustered environment, the driver can connect to any member within the cluster. Once connected, the driver will receive metadata about the cluster, known as a Routing Table.
Reading Data from Neo4j
The driver uses data from the Routing Table to distribute read statements across the cluster in a least-connected fashion, ensuring that the cluster is evenly utilised.
To execute a Cypher statement within a read transaction, call the neo4j.ExecuteRead()
method.
personNode, err := neo4j.ExecuteRead[neo4j.Node](
ctx, // (1)
session, // (2)
func(tx neo4j.ManagedTransaction) (neo4j.Node, error) { // (3)
result, err := tx.Run(ctx, cypher, params)
if err != nil {
return *new(neo4j.Node), err
}
// extract the single result
// and return it as a neo4j.Node
return neo4j.SingleTWithContext(ctx, result, // (4)
func(record *neo4j.Record) (neo4j.Node, error) {
node, _, err := neo4j.GetRecordValue[neo4j.Node](record, "p")
return node, err
}
)
}
)
The neo4j.ExecuteRead()
method expects the execution context (1), the session object (2) and a function to represent the unit of work (3).
The function has a single argument passed, an instance of a neo4j.ManagedTransaction
, on which the Run()
method can be called multiple times to execute Cypher statements.
The tx.Run()
method is similar to session.Run()
in that it accepts two parameters; a Cypher statement and an object representing the query parameters.
In the example above, the neo4j.SingleTWithContext()
function is used to extract the p
value from each returned record.
In this case, the return type has been cast as a neo4j.Node
.
If an error occurs for any reason during the transaction, the second returned value (err
) will provide more information.
Writing Data to Neo4j
The cluster will always contain one instance, known as the Leader, which has the responsibility of processing write transactions for a specific database. The Leader is responsible for distributing the transaction’s outcome across the cluster. Once the majority of core servers acknowledge this information, the transaction is considered committed and acknowledgement is sent back to the Driver along with any data requested by the Cypher statement.
To execute a Cypher statement within a write transaction, call the neo4j.ExecuteWrite()
method.
personNode, err := neo4j.ExecuteWrite[neo4j.Node](
ctx, // (1)
session, // (2)
func(tx neo4j.ManagedTransaction) (neo4j.Node, error) { // (3)
result, err := tx.Run(ctx, cypher, params)
if err != nil {
return *new(neo4j.Node), err
}
// extract the single result
// and return it as a neo4j.Node
return neo4j.SingleTWithContext(ctx, result, // (4)
func(record *neo4j.Record) (neo4j.Node, error) {
node, _, err := neo4j.GetRecordValue[neo4j.Node](record, "p")
return node, err
}
)
}
)
Check Your Understanding
Reading from Neo4j
Which method would you use to read data from Neo4j?
-
❏
ExecuteNeo4jRead()
-
✓
neo4j.ExecuteRead()
-
❏
session.ReadQuery()
-
❏
session.Read()
Hint
You are looking to execute a read query against the neo4j database.
Solution
The answer is neo4j.ExecuteRead()
Writing to Neo4j
Which method would you use to write data to Neo4j?
-
❏
ExecuteNeo4jWrite()
-
❏
neo4j.ExecuteRead()
-
✓
neo4j.ExecuteWrite()
-
❏
neo4j.Write()
Hint
You are looking to execute a read query against the neo4j database.
Solution
The answer is neo4j.ExecuteWrite()
Lesson Summary
In this lesson, you learned the best practices for reading data from and writing data to Neo4j.
You also learned how to access the records returned by session.Run()
and tx.Run()
.
In the next challenge, you will use this knowledge to execute a Cypher statement in a read transaction.