Chương này giới thiệu cách nhanh chóng bắt đầu với các hoạt động đọc và ghi của cơ sở dữ liệu vector Milvus bằng Go.
Cài đặt Go SDK
Lưu ý: Go SDK yêu cầu phiên bản Go 1.15 trở lên.
go get -u github.com/milvus-io/milvus-sdk-go/v2
Nhập các phụ thuộc
import (
"context"
"fmt"
"log"
"math/rand"
"time"
"github.com/milvus-io/milvus-sdk-go/v2/client"
"github.com/milvus-io/milvus-sdk-go/v2/entity"
)
Kết nối đến cơ sở dữ liệu Milvus
ctx := context.Background()
log.Printf(msgFmt, "Đang kết nối đến Milvus")
c, err := client.NewClient(ctx, client.Config{
Address: "localhost:19530",
})
if err != nil {
log.Fatal("Kết nối đến Milvus thất bại, lỗi: ", err.Error())
}
defer c.Close()
Tạo bộ sưu tập (Collection)
Quá trình tạo bộ sưu tập tương tự như việc tạo cấu trúc bảng MySQL, trong đó bạn cần mô tả loại của mỗi trường.
collectionName = "hello_tizi365"
log.Printf(msgFmt, fmt.Sprintf("Đang tạo bộ sưu tập, `%s`", collectionName))
// Định nghĩa loại trường của bộ sưu tập, ở đây định nghĩa các trường ID, random, và embeddings
schema := entity.NewSchema().WithName(collectionName).WithDescription("Mô tả bộ sưu tập").
WithField(entity.NewField().WithName("ID").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true).WithIsAutoID(false)).
WithField(entity.NewField().WithName("random").WithDataType(entity.FieldTypeDouble)).
WithField(entity.NewField().WithName("embeddings").WithDataType(entity.FieldTypeFloatVector).WithDim(dim))
// Tạo bộ sưu tập dựa trên loại trường bộ sưu tập được định nghĩa
if err := c.CreateCollection(ctx, schema, entity.DefaultShardNumber); err != nil {
log.Fatalf("Tạo bộ sưu tập thất bại, lỗi: %v", err)
}
Chèn dữ liệu vào bộ sưu tập
idList, randomList := make([]int64, 0, nEntities), make([]float64, 0, nEntities)
embeddingList := make([][]float32, 0, nEntities)
rand.Seed(time.Now().UnixNano())
// Ví dụ cho mục đích kiểm thử, tạo dữ liệu kiểm thử ngẫu nhiên ở đây
// Tạo IDs
for i := 0; i < nEntities; i++ {
idList = append(idList, int64(i))
}
// Tạo giá trị ngẫu nhiên
for i := 0; i < nEntities; i++ {
randomList = append(randomList, rand.Float64())
}
// Tạo giá trị vector
for i := 0; i < nEntities; i++ {
vec := make([]float32, 0, dim)
for j := 0; j < dim; j++ {
vec = append(vec, rand.Float32())
}
embeddingList = append(embeddingList, vec)
}
// Chèn nhiều bộ dữ liệu, tổ chức theo cột cho nhiều dữ liệu
idColData := entity.NewColumnInt64("ID", idList)
randomColData := entity.NewColumnDouble("random", randomList)
embeddingColData := entity.NewColumnFloatVector("embeddings", dim, embeddingList)
// Chèn dữ liệu
if _, err := c.Insert(ctx, collectionName, "", idColData, randomColData, embeddingColData); err != nil {
log.Fatalf("Ghi dữ liệu thất bại, lỗi: %v", err)
}
// Xả dữ liệu xuống đĩa
if err := c.Flush(ctx, collectionName, false); err != nil {
log.Fatalf("Xả dữ liệu thất bại, lỗi: %v", err)
}
Tạo chỉ mục (Index)
// Định nghĩa loại chỉ mục
idx, err := entity.NewIndexIvfFlat(entity.L2, 128)
if err != nil {
log.Fatalf("Định nghĩa chỉ mục thất bại, lỗi: %v", err)
}
// Tạo chỉ mục cho bộ sưu tập đã chỉ định
if err := c.CreateIndex(ctx, collectionName, embeddingCol, idx, false); err != nil {
log.Fatalf("Tạo chỉ mục thất bại, lỗi: %v", err)
}
// Tải bộ sưu tập đã chỉ định vào bộ nhớ để cải thiện hiệu suất truy vấn
err = c.LoadCollection(ctx, collectionName, false)
if err != nil {
log.Fatalf("Tải bộ sưu tập thất bại, lỗi: %v", err)
}
Tìm kiếm tương đồng vector
// Chuẩn bị các vector cần tìm kiếm. Ở đây chúng tôi trích xuất một phần dữ liệu vector từ dữ liệu đã tạo trước đó để kiểm tra, và chúng tôi sẽ tìm kiếm kết quả tương tự với các vector dưới đây.
vec2search := []entity.Vector{
entity.FloatVector(embeddingList[len(embeddingList)-2]),
entity.FloatVector(embeddingList[len(embeddingList)-1]),
}
begin := time.Now()
sp, _ := entity.NewIndexIvfFlatSearchParam(16)
// Thực hiện tìm kiếm tương đồng vector
sRet, err := c.Search(ctx, collectionName, nil, "", []string{"random"}, vec2search,
"embeddings", entity.L2, topK, sp)
end := time.Now()
if err != nil {
log.Fatalf("Tìm kiếm thất bại, lỗi: %v", err)
}
log.Println("In kết quả:")
for _, res := range sRet {
printResult(&res)
}
Định nghĩa hàm printResult
func printResult(sRet *client.SearchResult) {
randoms := make([]float64, 0, sRet.ResultCount)
scores := make([]float32, 0, sRet.ResultCount)
var randCol *entity.ColumnDouble
for _, field := range sRet.Fields {
if field.Name() == randomCol {
c, ok := field.(*entity.ColumnDouble)
if ok {
randCol = c
}
}
}
for i := 0; i < sRet.ResultCount; i++ {
val, err := randCol.ValueByIdx(i)
if err != nil {
log.Fatal(err)
}
randoms = append(randoms, val)
scores = append(scores, sRet.Scores[i])
}
log.Printf("\trandoms: %v, scores: %v\n", randoms, scores)
}
Toàn bộ mã nguồn minh họa, Mã nguồn Bắt đầu sử dụng Go Milvus