github.com/milvus-io/milvus-sdk-go/v2@v2.4.1/examples/array/hello_array.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  	"math/rand"
     8  	"time"
     9  
    10  	"github.com/milvus-io/milvus-sdk-go/v2/client"
    11  	"github.com/milvus-io/milvus-sdk-go/v2/entity"
    12  )
    13  
    14  const (
    15  	milvusAddr     = `127.0.0.1:19530`
    16  	nEntities, dim = 3000, 128
    17  	collectionName = "hello_array"
    18  
    19  	msgFmt                         = "==== %s ====\n"
    20  	idCol, randomCol, embeddingCol = "ID", "random", "embeddings"
    21  	topK                           = 3
    22  )
    23  
    24  func main() {
    25  	ctx := context.Background()
    26  
    27  	log.Printf(msgFmt, "start connecting to Milvus")
    28  	c, err := client.NewClient(ctx, client.Config{
    29  		Address: milvusAddr,
    30  	})
    31  	if err != nil {
    32  		log.Fatal("failed to connect to milvus, err: ", err.Error())
    33  	}
    34  	defer c.Close()
    35  
    36  	// delete collection if exists
    37  	has, err := c.HasCollection(ctx, collectionName)
    38  	if err != nil {
    39  		log.Fatalf("failed to check collection exists, err: %v", err)
    40  	}
    41  	if has {
    42  		c.DropCollection(ctx, collectionName)
    43  	}
    44  
    45  	// create collection
    46  	log.Printf(msgFmt, fmt.Sprintf("create collection, `%s`", collectionName))
    47  	schema := entity.NewSchema().WithName(collectionName).WithDescription("hello_array is the simplest demo to introduce the APIs").
    48  		WithField(entity.NewField().WithName(idCol).WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true).WithIsAutoID(false)).
    49  		WithField(entity.NewField().WithName(randomCol).WithDataType(entity.FieldTypeArray).WithElementType(entity.FieldTypeDouble).WithMaxCapacity(10)).
    50  		WithField(entity.NewField().WithName(embeddingCol).WithDataType(entity.FieldTypeFloatVector).WithDim(dim))
    51  
    52  	if err := c.CreateCollection(ctx, schema, entity.DefaultShardNumber); err != nil { // use default shard number
    53  		log.Fatalf("create collection failed, err: %v", err)
    54  	}
    55  
    56  	// insert data
    57  	log.Printf(msgFmt, "start inserting random entities")
    58  	idList, randomList := make([]int64, 0, nEntities), make([][]float64, 0, nEntities)
    59  	embeddingList := make([][]float32, 0, nEntities)
    60  
    61  	rand.Seed(time.Now().UnixNano())
    62  
    63  	// generate data
    64  	for i := 0; i < nEntities; i++ {
    65  		idList = append(idList, int64(i))
    66  	}
    67  	for i := 0; i < nEntities; i++ {
    68  		data := make([]float64, 0, 10)
    69  		for j := 0; j < 10; j++ {
    70  			data = append(data, rand.Float64())
    71  		}
    72  		randomList = append(randomList, data)
    73  	}
    74  	for i := 0; i < nEntities; i++ {
    75  		vec := make([]float32, 0, dim)
    76  		for j := 0; j < dim; j++ {
    77  			vec = append(vec, rand.Float32())
    78  		}
    79  		embeddingList = append(embeddingList, vec)
    80  	}
    81  	idColData := entity.NewColumnInt64(idCol, idList)
    82  	randomColData := entity.NewColumnDoubleArray(randomCol, randomList)
    83  	embeddingColData := entity.NewColumnFloatVector(embeddingCol, dim, embeddingList)
    84  
    85  	if _, err := c.Insert(ctx, collectionName, "", idColData, randomColData, embeddingColData); err != nil {
    86  		log.Fatalf("failed to insert random data into `hello_array, err: %v", err)
    87  	}
    88  
    89  	if err := c.Flush(ctx, collectionName, false); err != nil {
    90  		log.Fatalf("failed to flush data, err: %v", err)
    91  	}
    92  
    93  	// build index
    94  	log.Printf(msgFmt, "start creating index IVF_FLAT")
    95  	idx, err := entity.NewIndexIvfFlat(entity.L2, 128)
    96  	if err != nil {
    97  		log.Fatalf("failed to create ivf flat index, err: %v", err)
    98  	}
    99  	if err := c.CreateIndex(ctx, collectionName, embeddingCol, idx, false); err != nil {
   100  		log.Fatalf("failed to create index, err: %v", err)
   101  	}
   102  
   103  	log.Printf(msgFmt, "start loading collection")
   104  	err = c.LoadCollection(ctx, collectionName, false)
   105  	if err != nil {
   106  		log.Fatalf("failed to load collection, err: %v", err)
   107  	}
   108  
   109  	log.Printf(msgFmt, "start searcching based on vector similarity")
   110  	vec2search := []entity.Vector{
   111  		entity.FloatVector(embeddingList[len(embeddingList)-2]),
   112  		entity.FloatVector(embeddingList[len(embeddingList)-1]),
   113  	}
   114  	begin := time.Now()
   115  	sp, _ := entity.NewIndexIvfFlatSearchParam(16)
   116  	sRet, err := c.Search(ctx, collectionName, nil, "", []string{randomCol}, vec2search,
   117  		embeddingCol, entity.L2, topK, sp)
   118  	end := time.Now()
   119  	if err != nil {
   120  		log.Fatalf("failed to search collection, err: %v", err)
   121  	}
   122  
   123  	log.Println("results:")
   124  	for _, res := range sRet {
   125  		printResult(&res)
   126  	}
   127  	log.Printf("\tsearch latency: %dms\n", end.Sub(begin)/time.Millisecond)
   128  
   129  	// hybrid search
   130  	log.Printf(msgFmt, "start hybrid searching with `random[0] > 0.5`")
   131  	begin = time.Now()
   132  	sRet2, err := c.Search(ctx, collectionName, nil, "random[0] > 0.5",
   133  		[]string{randomCol}, vec2search, embeddingCol, entity.L2, topK, sp)
   134  	end = time.Now()
   135  	if err != nil {
   136  		log.Fatalf("failed to search collection, err: %v", err)
   137  	}
   138  	log.Println("results:")
   139  	for _, res := range sRet2 {
   140  		printResult(&res)
   141  	}
   142  	log.Printf("\tsearch latency: %dms\n", end.Sub(begin)/time.Millisecond)
   143  
   144  	// delete data
   145  	log.Printf(msgFmt, "start deleting with expr ``")
   146  	pks := entity.NewColumnInt64(idCol, []int64{0, 1})
   147  	sRet3, err := c.QueryByPks(ctx, collectionName, nil, pks, []string{randomCol})
   148  	if err != nil {
   149  		log.Fatalf("failed to query result, err: %v", err)
   150  	}
   151  	log.Println("results:")
   152  	idlist := make([]int64, 0)
   153  	randList := make([][]float64, 0)
   154  
   155  	for _, col := range sRet3 {
   156  		if col.Name() == idCol {
   157  			idColumn := col.(*entity.ColumnInt64)
   158  			for i := 0; i < col.Len(); i++ {
   159  				val, err := idColumn.ValueByIdx(i)
   160  				if err != nil {
   161  					log.Fatal(err)
   162  				}
   163  				idlist = append(idlist, val)
   164  			}
   165  		} else {
   166  			randColumn := col.(*entity.ColumnDoubleArray)
   167  			for i := 0; i < col.Len(); i++ {
   168  				val, err := randColumn.ValueByIdx(i)
   169  				if err != nil {
   170  					log.Fatal(err)
   171  				}
   172  				randList = append(randList, val)
   173  			}
   174  		}
   175  	}
   176  	log.Printf("\tids: %#v, randoms: %#v\n", idlist, randList)
   177  
   178  	if err := c.DeleteByPks(ctx, collectionName, "", pks); err != nil {
   179  		log.Fatalf("failed to delete by pks, err: %v", err)
   180  	}
   181  	_, err = c.QueryByPks(ctx, collectionName, nil, pks, []string{randomCol}, client.WithSearchQueryConsistencyLevel(entity.ClStrong))
   182  	if err != nil {
   183  		log.Printf("failed to query result, err: %v", err)
   184  	}
   185  
   186  	// drop collection
   187  	log.Printf(msgFmt, "drop collection `hello_array`")
   188  	if err := c.DropCollection(ctx, collectionName); err != nil {
   189  		log.Fatalf("failed to drop collection, err: %v", err)
   190  	}
   191  }
   192  
   193  func printResult(sRet *client.SearchResult) {
   194  	randoms := make([][]float64, 0, sRet.ResultCount)
   195  	scores := make([]float32, 0, sRet.ResultCount)
   196  
   197  	var randCol *entity.ColumnDoubleArray
   198  	for _, field := range sRet.Fields {
   199  		fmt.Println(field.Name())
   200  		if field.Name() == randomCol {
   201  			c, ok := field.(*entity.ColumnDoubleArray)
   202  			if ok {
   203  				randCol = c
   204  			}
   205  		}
   206  	}
   207  	for i := 0; i < sRet.ResultCount; i++ {
   208  		val, err := randCol.ValueByIdx(i)
   209  		if err != nil {
   210  			log.Fatal(err)
   211  		}
   212  		randoms = append(randoms, val)
   213  		scores = append(scores, sRet.Scores[i])
   214  	}
   215  	log.Printf("\trandoms: %v, scores: %v\n", randoms, scores)
   216  }