Go SDK对接向量数据库
本文介绍如何使用Go语言调用openGauss向量数据库。
环境要求
- 安装Go 1.19及以上版本。
安装SDK
开发者可以运行以下命令安装Go SDK官方仓库,并在项目中导入该包。
1. 安装SDK
2. go get gitcode.com/opengauss/openGauss-connector-go-pq@master
4. 在项目中导入该包
5. import (
6. "database/sql"
8. _ "gitcode.com/opengauss/openGauss-connector-go-pq"
9. )
说明: 目前 gitcode 不支持 go get,请参考下方用例指导手动安装。
基本操作
说明: 该仓库中所有资料和测试文件(copy_test.go,encode_test_go等)使用的密码及sslmode=disable仅为示例,在使用时,请根据实际情况配置正确的密码,使用安全的sslmode(默认值prefer)。
1.连接数据库
1. // connectInfo格式:
2. // "host=127.0.0.1 port=5432 user=username password=userpassword dbname=userdbname sslmode=disable"
3. func CreateDBClient(connectInfo string) (*sql.DB, error) {
4. return sql.Open("opengauss", connectInfo)
5. }
2.创建表
1. func CreateTable(client *sql.DB, dim int) error {
2. execSql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS demotable(id INTEGER, content TEXT, embedding vector(%d))", dim)
3. _, err := client.Exec(execSql)
4. return err
5. }
3.创建索引
1. // 用L2距离创建HNSW类型的向量索引
2. func CreateIndex(client *sql.DB) error {
3. execSql := fmt.Sprint("CREATE INDEX ON demotable USING hnsw (embedding vector_l2_ops)")
4. _, err := client.Exec(execSql)
5. return err
6. }
4.插入/删除/更新
- 插入
1. // 单条插入
2. type TableData struct {
3. Id int
4. Content string
5. Vector string
6. }
7. func InsertDataSingle(client *sql.DB, data TableData) error {
8. execSql := fmt.Sprintf("INSERT INTO demotable VALUES(%d, '%s', '%s')", data.Id, data.Content, data.Vector)
9. _, err := client.Exec(execSql)
10. return err
11. }
- 删除
1. func DeleteData(client *sql.DB) error {
2. execSql := fmt.Sprint("DELETE FROM demotable where id > 10")
3. _, err := client.Exec(execSql)
4. return err
5. }
- 更新
1. func UpdateData(client *sql.DB, vector string) error {
2. execSql := fmt.Sprintf("UPDATE demotable set embedding = '%s' where id = 10", vector)
3. _, err := client.Exec(execSql)
4. return err
5. }
5.查询
1. func SearchVectors(client *sql.DB, efsearch int, vector string, topK int) []string {
2. var res []string
3. // 设置查询参数
4. paramsql := fmt.Sprintf("set hnsw_ef_search = %d", efsearch);
5. querysql := fmt.Sprintf("SELECT * FROM demotable ORDER BY embedding <-> '%s' LIMIT %d;", vector, topK);
6. _, _ = client.Exec(paramsql)
7. rows, _ := client.Query(querysql)
8. for rows.Next() {
9. var id int
10. var content string
11. var vector []byte
12. _ = rows.Scan(&id, &content, &vector)
13. embedding := string(vector)
14. row := fmt.Sprintf("id: %d, content: %s, embedding: %s", id, content, embedding);
15. res = append(res, row)
16. }
17. return res
18. }
6.删除表
1. func DropTable(client *sql.DB, tableName string) error {
2. execSql := fmt.Sprintf("DROP TABLE IF EXISTS %s", tableName)
3. _, err := client.Exec(execSql)
4. return err
5. }
7.多向量并发查询
多向量召回支持在单次搜索请求中同时提交多个查询向量,openGauss将并行对查询向量进行搜索,并返回多组结果。
函数名
1. func ExecuteMultiSearch(conninfo string, query string, args [][]interface{}, scanParams map[string]interface{}, threadCount int)
输入参数
- conninfo:数据库连接配置,包含host、port、user、password、dbname
- query:查询语句,要求是单条查询语句(select为首单词)、包含向量操作符(<->/<=>/<#>/<+>/<~>/<%>)
- args:查询参数,要求不为空
- scanParams:需要通过set设置的参数(如hnsw_ef_search、nprobes)
- threadCount:连接池最大连接数,和数据库最大连接数(由参数max_connections设置)有关,一般来说,连接池最大连接数要小于数据库最大连接数,但是数据库对于管理员用户的连接限制会略超过max_connections设置。
输出参数
- 查询结果,形式为
[[map[id:1, embedding:'[1,2,3]'],map[id:2, embedding:'[2,2,2]']], [],...],表示n个查询向量对应的limit个结果。
使用案例
1. import (
2. "gitcode.com/opengauss/openGauss-connector-go-pq"
3. )
4. conninfo := "host=localhost port=5432 user=test password=yourpassword dbname=testdb"
5. scanParams := map[string]interface{}{
6. "hnsw_ef_search":"40",
7. "enable_seqscan":"off"
8. }
9. query := "select id from demotable order by embedding <-> $1 limit $2;"
10. threadCount := 2
11. args := [][]interface{}{
12. {"[1,2,3]", 2},
13. {"[2,2,2]", 3},
14. }
15. res := pq.ExecuteMultiSearch(conninfo, query, args, scanParams, threadCount)
用例指导
- 安装 openGauss-connector-go-pq
1. # 创建部署脚本
2. cat << 'EOL' > setup_opengauss_go.sh
3. #!/bin/bash
5. # 设置项目名称和驱动信息
6. PROJECT_NAME="opengauss-go"
7. MODULE_NAME="opengauss"
8. DRIVER_MODULE_PATH="gitcode.com/opengauss/openGauss-connector-go-pq"
9. DRIVER_REPO_URL="https://$DRIVER_MODULE_PATH.git"
10. DRIVER_VERSION="v1.0.7"
12. # 获取 GOPATH
13. GOPATH=$(go env GOPATH)
14. DRIVER_LOCAL_PATH="$GOPATH/src/$DRIVER_MODULE_PATH"
16. # 创建项目目录并初始化 go mod
17. echo "🚀 初始化 Go 项目..."
18. mkdir -p "$PROJECT_NAME"
19. cd "$PROJECT_NAME" || exit 1
20. go mod init "$MODULE_NAME"
22. # 克隆 openGauss 驱动到本地路径
23. echo "📦 正在克隆 openGauss Go 驱动..."
24. mkdir -p "$DRIVER_LOCAL_PATH"
25. git clone "$DRIVER_REPO_URL" "$DRIVER_LOCAL_PATH"
27. # 修改 go.mod 添加 require 和 replace
28. echo "⚙️ 更新 go.mod 文件..."
29. cat <<EOL2 >> go.mod
31. require $DRIVER_MODULE_PATH $DRIVER_VERSION
33. replace $DRIVER_MODULE_PATH => $DRIVER_LOCAL_PATH
34. EOL2
36. # 清理模块缓存以确保生效
37. echo "🧹 清理模块缓存..."
38. go clean -modcache
40. # 下载依赖
41. echo "📥 安装依赖包..."
42. go get "$DRIVER_MODULE_PATH"
44. echo "✅ 初始化和依赖安装完成!"
45. EOL
47. # 赋予可执行权限
48. chmod +x setup_opengauss_go.sh
50. # 执行脚本,开始安装
51. ./setup_opengauss_go.sh
- **使用 Go SDK 连接 openGauss 执行向量操作 **
1. # 创建main.go,填入一下内容
2. vim main.go
3. package main
4. import (
5. "fmt"
6. "log"
7. "database/sql"
9. _ "gitcode.com/opengauss/openGauss-connector-go-pq"
10. )
12. /*
13. * 将上述创建、删除等函数复制到此处
14. */
16. func main(){
17. connStr := "host=YourIP port=YourPort user=YourUserName password=YourPassWord dbname=YourDBName sslmode=disable"
18. dbClient, err := CreateDBClient(connStr)
19. if err != nil {
20. log.Fatal(err)
21. }
23. err = DropTable(dbClient, "demotable")
24. err = CreateTable(dbClient, 3)
25. err = CreateIndex(dbClient)
27. data := TableData{
28. Id: 1,
29. Content: "test",
30. Vector: "[1,2,3]",
31. }
32. err = InsertDataSingle(dbClient, data)
34. data = TableData{
35. Id: 11,
36. Content: "test1",
37. Vector: "[3,4,5]",
38. }
39. err = InsertDataSingle(dbClient, data)
41. data = TableData{
42. Id: 10,
43. Content: "test3",
44. Vector: "[2,2,2]",
45. }
46. err = InsertDataSingle(dbClient, data)
48. err = UpdateData(dbClient, "[3,3,3]")
50. err = DeleteData(dbClient)
52. vectors := SearchVectors(dbClient, 1, "[3,2,4]", 5)
53. fmt.Println(vectors)
54. err = DropTable(dbClient, "demotable")
55. }
说明:
目前 gitcode 不支持 go get,请参考下方用例指导手动安装。