Source: https://dev-docs.yueshu.com.cn/v5.3.2/clients/go-client/ Documentation version: v5.3.2 # Go SDK 指南 本文介绍如何使用 [Go SDK](https://github.com/vesoft-inc/nebula-go/tree/v5.3.0) 连接悦数图数据库开发版并进行简单查询。 ## 前提条件 - 对于本地部署用户,悦数图数据库开发版服务组正在运行中。更多信息,请参见[快速开始](https://dev-docs.yueshu.com.cn/v5.3.2/get-started/deploy/)。 ## 操作步骤 1. 修改 Go 模块依赖项以使用 Go SDK 的本地版本。例如: ```` workspace=/app/myapp # 在 Go 项目中,运行 go mod edit cd ${workspace} go get github.com/vesoft-inc/nebula-go/v5@5.3.0 ```` 更多信息,请参见 [go.mod 文件参考](https://go.dev/doc/modules/gomod-ref#replace)。 2. 使用 SDK 连接悦数图数据库开发版并执行查询,例如: Note 针对本地部署用户,在连接悦数图数据库开发版时,除了指定用户名和密码外,还可以启用无会话模式。该模式允许您不提供身份验证信息。更多信息,请参见[无会话模式](https://dev-docs.yueshu.com.cn/v5.3.2/server-admin/authentication/sessionless/)。 ```` package main import ( "fmt" nebula "github.com/vesoft-inc/nebula-go/v5" ) const ( address = ":" username = "" password = "" ) // Initialize logger var log = nebula.DefaultLogger func basicClient() { client, err := nebula.NewNebulaClient(address, username, password) if err != nil { log.Error(err.Error()) return } resp, err := client.Execute("return 1 as a") if err != nil { log.Error(err.Error()) return } log.Info(fmt.Sprintf("columns: %v", resp.Columns())) for resp.HasNext() { row, err := resp.Next() if err != nil { log.Error(err.Error()) return } v1, err := row.GetValueByIndex(0) if err != nil { log.Error(err.Error()) return } log.Info(v1.String()) v2, err := row.GetValueByName("a") if err != nil { log.Error(err.Error()) return } log.Info(v2.String()) } } func basicPool() { pool, err := nebula.NewNebulaPool(address, username, password) if err != nil { log.Error(err.Error()) return } client, err := pool.GetClient() if err != nil { log.Error(err.Error()) return } resp, err := client.Execute("return 1 as a") if err != nil { log.Error(err.Error()) return } log.Info(fmt.Sprintf("columns: %v", resp.Columns())) for resp.HasNext() { row, err := resp.Next() if err != nil { log.Error(err.Error()) return } v1, err := row.GetValueByIndex(0) if err != nil { log.Error(err.Error()) return } log.Info(v1.String()) v2, err := row.GetValueByName("a") if err != nil { log.Error(err.Error()) return } log.Info(v2.String()) } } func main() { basicClient() basicPool() } ```` 若目标图不在默认 Schema(`/default_schema`)中,可按以下方式指定 Schema: ```` // 方式一:对于 NewNebulaClient 获取的 client,手动设置 Schema 和图 _, err = client.Execute("SESSION SET SCHEMA /my_schema") if err != nil { log.Error(err.Error()) return } _, err = client.Execute("USE my_graph") if err != nil { log.Error(err.Error()) return } resp, err = client.Execute("MATCH (v) RETURN v LIMIT 10") if err != nil { log.Error(err.Error()) return } // 方式二:对于 NewNebulaPool,可在初始化时指定 Schema 和图 pool, err := nebula.NewNebulaPool( address, username, password, nebula.WithPoolSchema("/my_schema"), nebula.WithPoolGraph("my_graph"), ) if err != nil { log.Error(err.Error()) return } defer pool.Close() client2, err := pool.GetClient() if err != nil { log.Error(err.Error()) return } defer pool.PutClient(client2) resp, err = client2.Execute("MATCH (v) RETURN v LIMIT 10") if err != nil { log.Error(err.Error()) return } ```` 使用连接池时,`WithPoolSchema`和`WithPoolGraph`会在连接创建时自动设置会话上下文。若未指定`WithPoolSchema`,新建会话将使用默认 Schema(例如`/default_schema`)。 更多信息,请参见 [SESSION SET SCHEMA](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/sessions/set/) 和 [USE 子句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/clauses/use-graph/)。 参数``、``、``和``须替换为实际的悦数图数据库开发版连接信息。 ## 最佳实践 在处理查询结果时,您可以使用以下任一方法来存储结果值: - 方法一:在循环内声明结构体变量 ```` resp, err = client.Execute(query) if err != nil { log.Error(fmt.Sprintf("Failed to execute query: %v", err)) return } for resp.HasNext() { var p Person if err := resp.Scan(&p.id, &p.birthday, &p.firstName); err != nil { log.Error(fmt.Sprintf("Failed to scan row: %v", err)) return } if p.id.Valid && p.birthday.Valid && p.firstName.Valid { fmt.Printf("id: %d, ", p.id.Data) fmt.Printf("birthday: %d-%d-%d, ", p.birthday.Data.GetYear(), p.birthday.Data.GetMonth(), p.birthday.Data.GetDay()) fmt.Printf("first name: %s\n", p.firstName.Data) } } ```` - 方法二:在循环外声明结构体变量 ```` resp, err = client.Execute(query) if err != nil { log.Error(fmt.Sprintf("Failed to execute query: %v", err)) return } var p Person for resp.HasNext() { if err := resp.Scan(&p.id, &p.birthday, &p.firstName); err != nil { log.Error(fmt.Sprintf("Failed to scan row: %v", err)) return } if p.id.Valid && p.birthday.Valid && p.firstName.Valid { fmt.Printf("id: %d, ", p.id.Data) fmt.Printf("birthday: %d-%d-%d, ", p.birthday.Data.GetYear(), p.birthday.Data.GetMonth(), p.birthday.Data.GetDay()) fmt.Printf("first name: %s\n", p.firstName.Data) } } ```` 在上述两种方法中,查询结果被扫描到`Person`结构体中,其定义如下: ```` type Person struct { id nebula.NullInt64 birthday nebula.NullDate firstName nebula.NullString } ```` 在方法一中,`Person`结构体在循环内声明,因此每次迭代都会创建一个新的`p`实例。在方法二中,它在循环外声明,因此每次迭代都重用同一个`p`实例。两种方法均可用,但方法二在处理数据量较大结果集时,在内存使用和性能方面更为高效。 ## 更多信息 - [更多示例](https://github.com/vesoft-inc/nebula-go/tree/v5.3.0/doc/zh)