Skip to content

Commit 8556d8f

Browse files
committed
Update Go samples to use v5 driver and ExecuteQuery
1 parent b4dc295 commit 8556d8f

File tree

4 files changed

+68
-118
lines changed

4 files changed

+68
-118
lines changed

code/go/example.go

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
package main
44

55
import (
6+
"context"
67
"fmt"
7-
"github.com/neo4j/neo4j-go-driver/v4/neo4j"
8-
"io"
8+
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
99
"reflect"
1010
)
1111

@@ -19,45 +19,36 @@ func main() {
1919
}
2020
}
2121

22-
func runQuery(uri, database, username, password string) (result []string, err error) {
23-
driver, err := neo4j.NewDriver(uri, neo4j.BasicAuth(username, password, ""))
22+
func runQuery(uri, database, username, password string) (_ []string, err error) {
23+
ctx := context.Background()
24+
driver, err := neo4j.NewDriverWithContext(uri, neo4j.BasicAuth(username, password, ""))
2425
if err != nil {
2526
return nil, err
2627
}
27-
defer func() {err = handleClose(driver, err)}()
28-
session := driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeRead, DatabaseName: database})
29-
defer func() {err = handleClose(session, err)}()
30-
results, err := session.ReadTransaction(func(transaction neo4j.Transaction) (interface{}, error) {
31-
result, err := transaction.Run(
32-
`
33-
MATCH (m:Movie {title:$movieTitle})<-[:ACTED_IN]-(a:Person) RETURN a.name as actorName
34-
`, map[string]interface{}{
35-
"movieTitle": "The Matrix",
36-
})
28+
defer func() { err = handleClose(ctx, driver, err) }()
29+
query := "MATCH (m:Movie {title:$movieTitle})<-[:ACTED_IN]-(a:Person) RETURN a.name as actorName"
30+
params := map[string]any{"movieTitle": "The Matrix"}
31+
result, err := neo4j.ExecuteQuery(ctx, driver, query, params,
32+
neo4j.EagerResultTransformer,
33+
neo4j.ExecuteQueryWithDatabase(database),
34+
neo4j.ExecuteQueryWithReadersRouting())
35+
if err != nil {
36+
return nil, err
37+
}
38+
actorNames := make([]string, len(result.Records))
39+
for i, record := range result.Records {
40+
// this assumes all actors have names, hence ignoring the 2nd returned value
41+
name, _, err := neo4j.GetRecordValue[string](record, "actorName")
3742
if err != nil {
3843
return nil, err
3944
}
40-
var arr []string
41-
for result.Next() {
42-
value, found := result.Record().Get("actorName")
43-
if found {
44-
arr = append(arr, value.(string))
45-
}
46-
}
47-
if err = result.Err(); err != nil {
48-
return nil, err
49-
}
50-
return arr, nil
51-
})
52-
if err != nil {
53-
return nil, err
45+
actorNames[i] = name
5446
}
55-
result = results.([]string)
56-
return result, err
47+
return actorNames, nil
5748
}
5849

59-
func handleClose(closer io.Closer, previousError error) error {
60-
err := closer.Close()
50+
func handleClose(ctx context.Context, closer interface{ Close(context.Context) error }, previousError error) error {
51+
err := closer.Close(ctx)
6152
if err == nil {
6253
return previousError
6354
}

code/go/example_aura.go

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,23 @@
11
package main
2+
23
import (
4+
"context"
35
"fmt"
4-
"github.com/neo4j/neo4j-go-driver/neo4j"
6+
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
57
)
8+
69
func main() {
7-
var driver neo4j.Driver
8-
var err error
9-
// Aura requires you to use "bolt+routing" protocol, and process your queries using an encrypted connection
10+
ctx := context.Background()
11+
// Aura requires you to use "neo4j+s" scheme, so that your queries are processed using an encrypted connection
1012
// (You may need to replace your connection details, username and password)
11-
boltURL := "bolt+routing://<Bolt url for Neo4j Aura database>"
13+
uri := "neo4j+s://<Bolt url for Neo4j Aura database>"
1214
auth := neo4j.BasicAuth("<Username for Neo4j Aura database>", "<Password for Neo4j Aura database>", "")
13-
14-
configurers := []func(*neo4j.Config){
15-
func (config *neo4j.Config) {
16-
config.Encrypted = true
17-
},
18-
}
19-
if driver, err = neo4j.NewDriver(boltURL, auth, configurers...); err != nil {
15+
driver, err := neo4j.NewDriverWithContext(uri, auth)
16+
if err != nil {
2017
panic(err)
2118
}
22-
2319
// Don't forget to close the driver connection when you are finished with it
24-
defer driver.Close()
25-
26-
var writeSession neo4j.Session
27-
// Using write transactions allow the driver to handle retries and transient errors for you
28-
if writeSession, err = driver.Session(neo4j.AccessModeWrite); err != nil {
29-
panic(err)
30-
}
31-
defer writeSession.Close()
20+
defer closeResource(ctx, driver)
3221

3322
// To learn more about the Cypher syntax, see https://neo4j.com/docs/cypher-manual/current/
3423
// The Reference Card is also a good resource for keywords https://neo4j.com/docs/cypher-refcard/current/
@@ -37,52 +26,54 @@ func main() {
3726
MERGE (p2:Person { name: $person2_name })
3827
MERGE (p1)-[:KNOWS]->(p2)
3928
RETURN p1, p2`
40-
41-
var result neo4j.Result
42-
result, err = writeSession.Run(createRelationshipBetweenPeopleQuery, map[string]interface{}{
29+
params := map[string]any{
4330
"person1_name": "Alice",
4431
"person2_name": "David",
45-
})
32+
}
4633

34+
// Using ExecuteQuery allows the driver to handle retries and transient errors for you
35+
result, err := neo4j.ExecuteQuery(ctx, driver, createRelationshipBetweenPeopleQuery, params,
36+
neo4j.EagerResultTransformer)
4737
if err != nil {
4838
panic(err)
4939
}
50-
51-
// You should capture any errors along with the query and data for traceability
52-
if result.Err() != nil {
53-
panic(result.Err())
40+
for _, record := range result.Records {
41+
fmt.Printf("First: '%s'\n", getPersonName(record, "p1"))
42+
fmt.Printf("Second: '%s'\n", getPersonName(record, "p2"))
5443
}
5544

56-
for result.Next() {
57-
firstPerson := result.Record().GetByIndex(0).(neo4j.Node)
58-
fmt.Printf("First: '%s'\n", firstPerson.Props()["name"].(string))
59-
secondPerson := result.Record().GetByIndex(1).(neo4j.Node)
60-
fmt.Printf("Second: '%s'\n", secondPerson.Props()["name"].(string))
61-
}
62-
63-
var readSession neo4j.Session
64-
65-
if readSession, err = driver.Session(neo4j.AccessModeRead); err != nil {
66-
panic(err)
67-
}
68-
defer readSession.Close()
69-
7045
readPersonByName := `
7146
MATCH (p:Person)
7247
WHERE p.name = $person_name
7348
RETURN p.name AS name`
74-
75-
result, err = readSession.Run(readPersonByName, map[string]interface{}{"person_name": "Alice"})
76-
49+
result, err = neo4j.ExecuteQuery(ctx, driver, readPersonByName, map[string]any{"person_name": "Alice"},
50+
neo4j.EagerResultTransformer)
7751
if err != nil {
7852
panic(err)
7953
}
54+
for _, record := range result.Records {
55+
name, _, err := neo4j.GetRecordValue[string](record, "name")
56+
if err != nil {
57+
panic(err)
58+
}
59+
fmt.Printf("Person name: '%s' \n", name)
60+
}
61+
}
8062

81-
if result.Err() != nil {
82-
panic(result.Err())
63+
func closeResource(ctx context.Context, closer interface{ Close(context.Context) error }) {
64+
if err := closer.Close(ctx); err != nil {
65+
panic(err)
8366
}
67+
}
8468

85-
for result.Next() {
86-
fmt.Printf("Person name: '%s' \n", result.Record().GetByIndex(0).(string))
69+
func getPersonName(record *neo4j.Record, key string) string {
70+
firstPerson, _, err := neo4j.GetRecordValue[neo4j.Node](record, key)
71+
if err != nil {
72+
panic(err)
73+
}
74+
firstPersonName, err := neo4j.GetProperty[string](firstPerson, "name")
75+
if err != nil {
76+
panic(err)
8777
}
78+
return firstPersonName
8879
}

code/go/go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module example
22

3-
go 1.14
3+
go 1.20
44

5-
require github.com/neo4j/neo4j-go-driver v1.8.0
5+
require github.com/neo4j/neo4j-go-driver/v5 v5.8.0

code/go/go.sum

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,2 @@
1-
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2-
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
3-
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
4-
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
5-
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
6-
github.com/neo4j/neo4j-go-driver v1.8.0 h1:YRp9jsFcF9k/AnvbcqFCN9OMeIT2XTJgxOpp2Puq7OE=
7-
github.com/neo4j/neo4j-go-driver v1.8.0/go.mod h1:0A49wIv0oP3uQdnbceK7Kc+snlY5B0F6dmtYArM0ltk=
8-
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
9-
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
10-
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
11-
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
12-
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
13-
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
14-
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
15-
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
16-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
17-
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
18-
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
19-
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
20-
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
21-
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
22-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
23-
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
24-
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
25-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
26-
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
27-
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
28-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
29-
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
30-
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
31-
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
32-
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
33-
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
34-
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
1+
github.com/neo4j/neo4j-go-driver/v5 v5.8.0 h1:I+jtnFbbN9FvRP5etOsrdJNNEThHUCe6pO0MFk1md04=
2+
github.com/neo4j/neo4j-go-driver/v5 v5.8.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k=

0 commit comments

Comments
 (0)