Dieses Kapitel bietet eine Einführung in die schnelle Inbetriebnahme der Lese- und Schreiboperationen der Milvus-Vektordatenbank mit Go.

Installation des Go SDK

Hinweis: Das Go SDK erfordert Go-Version 1.15 oder höher.

go get -u github.com/milvus-io/milvus-sdk-go/v2

Abhängigkeiten importieren

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"
)

Verbindung zur Milvus-Datenbank herstellen

	ctx := context.Background()

	log.Printf(msgFmt, "Verbindung zu Milvus herstellen")
	c, err := client.NewClient(ctx, client.Config{
		Address: "localhost:19530",
	})
	if err != nil {
		log.Fatal("Verbindung zu Milvus fehlgeschlagen, Fehler: ", err.Error())
	}
	defer c.Close()

Erstellung einer Sammlung

Der Prozess der Erstellung einer Sammlung ist ähnlich wie die Strukturierung einer MySQL-Tabelle, bei der Sie den Typ jedes Feldes beschreiben müssen.

   collectionName = "hello_tizi365"
	log.Printf(msgFmt, fmt.Sprintf("Sammlung erstellen, `%s`", collectionName))
	
	// Definieren der Feldtypen der Sammlung, hier werden ID, Zufall und Einbettungsfelder definiert
	schema := entity.NewSchema().WithName(collectionName).WithDescription("Sammlungsbeschreibung").
		WithField(entity.NewField().WithName("ID").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true).WithIsAutoID(false)).
		WithField(entity.NewField().WithName("zufall").WithDataType(entity.FieldTypeDouble)).
		WithField(entity.NewField().WithName("einbettungen").WithDataType(entity.FieldTypeFloatVector).WithDim(dim))

	// Erstellen der Sammlung basierend auf den definierten Sammlungsfeldtypen
	if err := c.CreateCollection(ctx, schema, entity.DefaultShardNumber); err != nil {
		log.Fatalf("Fehler beim Erstellen der Sammlung, Fehler: %v", err)
	}

Einfügen von Daten in die Sammlung

	idList, randomList := make([]int64, 0, nEntities), make([]float64, 0, nEntities)
	embeddingList := make([][]float32, 0, nEntities)

	rand.Seed(time.Now().UnixNano())

    // Zur Testzwecken hier einige zufällige Testdaten generieren
	// IDs generieren
	for i := 0; i < nEntities; i++ {
		idList = append(idList, int64(i))
	}
	// Zufallswerte generieren
	for i := 0; i < nEntities; i++ {
		randomList = append(randomList, rand.Float64())
	}
	// Vektorwerte generieren
	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)
	}
	// Mehrere Datensätze einfügen, nach Spalte für mehrere Daten organisiert
	idColData := entity.NewColumnInt64("ID", idList)
	randomColData := entity.NewColumnDouble("zufall", randomList)
	embeddingColData := entity.NewColumnFloatVector("einbettungen", dim, embeddingList)

    // Daten einfügen
	if _, err := c.Insert(ctx, collectionName, "", idColData, randomColData, embeddingColData); err != nil {
		log.Fatalf("Fehler beim Schreiben von Daten, Fehler: %v", err)
	}
    
	// Daten auf die Festplatte schreiben
	if err := c.Flush(ctx, collectionName, false); err != nil {
		log.Fatalf("Fehler beim Schreiben von Daten auf die Festplatte, Fehler: %v", err)
	}

Index erstellen

	// Indextyp definieren
	idx, err := entity.NewIndexIvfFlat(entity.L2, 128)
	if err != nil {
		log.Fatalf("Fehler beim Definieren des Index, Fehler: %v", err)
	}
	// Index für die angegebene Sammlung erstellen
	if err := c.CreateIndex(ctx, collectionName, embeddingCol, idx, false); err != nil {
		log.Fatalf("Fehler beim Erstellen des Index, Fehler: %v", err)
	}

    // Laden der angegebenen Sammlung in den Speicher, um die Abfrageeffizienz zu verbessern
	err = c.LoadCollection(ctx, collectionName, false)
	if err != nil {
		log.Fatalf("Fehler beim Laden der Sammlung, Fehler: %v", err)
	}
// Vorbereiten der Vektoren, die durchsucht werden sollen. Hier extrahieren wir einen Teil der Vektordaten aus den zuvor generierten Daten zum Testen, und wir werden nach Ergebnissen suchen, die diesen unten stehenden Vektoren ähnlich sind.
vec2search := []entity.Vector{
    entity.FloatVector(embeddingList[len(embeddingList)-2]),
    entity.FloatVector(embeddingList[len(embeddingList)-1]),
}
begin := time.Now()
sp, _ := entity.NewIndexIvfFlatSearchParam(16)
// Führen Sie die Vektorsimilaritätssuche durch
sRet, err := c.Search(ctx, collectionName, nil, "", []string{"zufällig"}, vec2search,
    "embeddings", entity.L2, topK, sp)
end := time.Now()
if err != nil {
    log.Fatalf("Suche fehlgeschlagen, Fehler: %v", err)
}

log.Println("Ergebnisse drucken:")
for _, res := range sRet {
    printResult(&res)
}

printResult Funktion Definition

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() == "zufällig" {
            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("\tzufällig: %v, Ergebnisse: %v\n", randoms, scores)
}

Vollständiger Demonstrationsquellcode, Go Milvus Getting Started Source Code