暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

golang操作向量数据库qdrant

    完成通过langchain框架使用大模型后,我们学习golang操作向量数据库,qdrant向量数据库支持http协议和grpc协议。grpc协议有个客户端库
github.com/qdrant/go-client/qdrant
    首先看下如何使用这个库连接qdrant
    package main
    import (
        "fmt"
        "github.com/qdrant/go-client/qdrant"
    )


    func main() {
        client, err := qdrant.NewClient(&qdrant.Config{
            Host: "localhost",
            Port: 6334,
          })
          if err!= nil {
            panic(err)
          }
          fmt.Println(client)
    }
        需要注意的是这里的grpc端口是6334,如果使用6333的话会报如下错误,因为6333是http协议端口
      2025/04/05 16:08:22 WARN Unable to get server version, use default err="rpc error: code = Unavailable desc = connection error: desc = \"error reading server preface: http2: frame too large\"" default=Unknown
      2025/04/05 16:08:22 WARN Failed to obtain server version. Unable to check client-server compatibility. Set SkipCompatibilityCheck=true to skip version check.
              接着可以使用对应的函数来进行向量的增删改查,CreateCollection来创建集合,需要指定的参数是向量的大小,和计算距离的函数,这里使用的是cos函数,然后使用Upsert向集合里添加点,每个点包含三个元素,ID、向量、和负载。最后通过Query函数来进行查询,查询的时候需要传入一个向量。并且可以添加查询过滤条件,对负载进行过滤,并决定是否要返回负载内容:
        package main
        import (
            "context"
            "fmt"
            "github.com/qdrant/go-client/qdrant"
        )
        func main() {
            client, err := qdrant.NewClient(&qdrant.Config{
                Host"localhost",
                Port6334,
              })
              if err!= nil {
                panic(err)
              }
              fmt.Println(client)
            err=client.CreateCollection(context.Background(), &qdrant.CreateCollection{
                CollectionName"example_collection",
                VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
                    Size:     4,
                    Distance: qdrant.Distance_Cosine,
                }),
            })
            if err!= nil {
                panic(err)
            }
            operationInfo, err := client.Upsert(context.Background(), &qdrant.UpsertPoints{
                CollectionName"example_collection",
                Points: []*qdrant.PointStruct{
                    {
                        Id:      qdrant.NewIDNum(1),
                        Vectors: qdrant.NewVectors(0.050.610.760.74),
                        Payload: qdrant.NewValueMap(map[string]any{"city""London"}),
                    },
                    {
                        Id:      qdrant.NewIDNum(2),
                        Vectors: qdrant.NewVectors(0.190.810.750.11),
                        Payload: qdrant.NewValueMap(map[string]any{"age"32}),
                    },
                    {
                        Id:      qdrant.NewIDNum(3),
                        Vectors: qdrant.NewVectors(0.360.550.470.94),
                        Payload: qdrant.NewValueMap(map[string]any{"vegan"true}),
                    },
                },
            })
            if err != nil {
                panic(err)
            }
            fmt.Println(operationInfo)
            searchResult, err := client.Query(context.Background(), &qdrant.QueryPoints{
                CollectionName"example_collection",
                Query:          qdrant.NewQuery(0.20.10.90.7),
            })
            if err != nil {
                panic(err)
            }
            fmt.Println(searchResult)
            searchResult, err = client.Query(context.Background(), &qdrant.QueryPoints{
                CollectionName"example_collection",
                Query:          qdrant.NewQuery(0.20.10.90.7),
                Filter: &qdrant.Filter{
                    Must: []*qdrant.Condition{
                        qdrant.NewMatch("city""London"),
                    },
                },
                WithPayload: qdrant.NewWithPayload(true),
            })
            if err != nil {
                panic(err)
            }
            fmt.Println(searchResult)
        }


             如果条件不适合使用grpc,也可以自己手写http请求,走http协议,下面是一个简单的例子:
          package main
          import(
              "net/http"
              "bytes"
              "encoding/json"
              "io/ioutil"
              "fmt"
          )
          func main() {
              createCollection()
              addData()
          }


          func createCollection() {
          data := Payload {
              // fill struct
              Vectors {
                  Size: 768,
                  Distance: "Dot",
              },
          }
          payloadBytes, err := json.Marshal(data)
          if err != nil {
              // handle err
          }
          body := bytes.NewReader(payloadBytes)
          req, err := http.NewRequest(http.MethodPut, "http://localhost:6333/collections/romeo", body)
          if err != nil {
              // handle err
          }
          req.Header.Set("Content-Type""application/json")
          resp, err := http.DefaultClient.Do(req)
          if err != nil {
              // handle err
          }
          defer resp.Body.Close()
          if resp.StatusCode != http.StatusOK {
              // handle err
              
          }
          // handle response
          responseBytes, err := ioutil.ReadAll(resp.Body)
          if err != nil {
              // handle err
          }
          responseData := Payload{}
          err = json.Unmarshal(responseBytes, &responseData)
          if err != nil {
              // handle err   
          }   
          fmt.Println(string(responseBytes))
          }   
          func addData() {
          data := AddReq{
          // fill struct
              Points: []Points{
                  Points{
                      ID: 1,
                      Vector: []float64{0.050.610.760.74},
                      Payload: AddPayload{
                          Colony: "Mars",
                      },
                  },
                  Points{
                      ID: 2,
                      Vector: []float64{0.190.810.750.11},
                      Payload: AddPayload{
                          Colony: "Jupiter",
                      },
                  },
                  Points{
                      ID: 3,
                      Vector: []float64{0.360.550.470.94},
                      Payload: AddPayload{
                          Colony: "Venus",
                      },
                  },
                  Points{
                      ID: 4,
                      Vector: []float64{0.180.010.850.80},
                      Payload: AddPayload{
                          Colony: "Moon",
                      },
                  },
                  Points{
                      ID: 5,
                      Vector: []float64{0.240.180.220.44},
                      Payload: AddPayload{
                          Colony: "Pluto",
                      },
                  },  
              },
          }
          payloadBytes, err := json.Marshal(data)
          if err != nil {
              // handle err
          }
          body := bytes.NewReader(payloadBytes)
          req, err := http.NewRequest(http.MethodPut, "http://localhost:6333/collections/star_charts/points", body)
          if err != nil {
              // handle err
          }
          req.Header.Set("Content-Type""application/json")
          resp, err := http.DefaultClient.Do(req)
          if err != nil {
              // handle err
          }
          defer resp.Body.Close()
          if resp.StatusCode != http.StatusOK {
              // handle err
          }
          // handle response
          responseBytes, err := ioutil.ReadAll(resp.Body)
          if err != nil {
              // handle err
          }
          responseData := Payload{}
          err = json.Unmarshal(responseBytes, &responseData)
          if err != nil {
              // handle err   
          }
          fmt.Println(string(responseBytes))
          }


          type Payload struct {
              Vectors Vectors `json:"vectors"`
          }
          type Vectors struct {
              Size int `json:"size"`
              Distance string `json:"distance"`
          }




          type AddReq struct {
              Points []Points `json:"points"`
          }
          type AddPayload struct {
              Colony string `json:"colony"`
          }
          type Points struct {
              ID      int       `json:"id"`
              Vector  []float64 `json:"vector"`
              Payload AddPayload   `json:"payload"`
          }
                创建collection的路径是 http://localhost:6333/collections/{collection_name},保存数据的路径是
          http://localhost:6333/collections/{collection_name}/points,返回值如下:
            {"status":{"error":"Wrong input: Collection `romeo` already exists!"},"time":0.00016268}
            {"result":{"operation_id":2,"status":"acknowledged"},"status":"ok","time":0.010663987}

            文章转载自golang算法架构leetcode技术php,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论