github.com/milvus-io/milvus-sdk-go/v2@v2.4.1/examples/hello_milvus/hello_milvus.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 = `localhost:19530` 16 nEntities, dim = 3000, 128 17 collectionName = "hello_milvus" 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_milvus 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.FieldTypeDouble)). 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 randomList = append(randomList, rand.Float64()) 69 } 70 for i := 0; i < nEntities; i++ { 71 vec := make([]float32, 0, dim) 72 for j := 0; j < dim; j++ { 73 vec = append(vec, rand.Float32()) 74 } 75 embeddingList = append(embeddingList, vec) 76 } 77 idColData := entity.NewColumnInt64(idCol, idList) 78 randomColData := entity.NewColumnDouble(randomCol, randomList) 79 embeddingColData := entity.NewColumnFloatVector(embeddingCol, dim, embeddingList) 80 81 if _, err := c.Insert(ctx, collectionName, "", idColData, randomColData, embeddingColData); err != nil { 82 log.Fatalf("failed to insert random data into `hello_milvus, err: %v", err) 83 } 84 85 if err := c.Flush(ctx, collectionName, false); err != nil { 86 log.Fatalf("failed to flush data, err: %v", err) 87 } 88 89 // build index 90 log.Printf(msgFmt, "start creating index IVF_FLAT") 91 idx, err := entity.NewIndexIvfFlat(entity.L2, 128) 92 if err != nil { 93 log.Fatalf("failed to create ivf flat index, err: %v", err) 94 } 95 if err := c.CreateIndex(ctx, collectionName, embeddingCol, idx, false); err != nil { 96 log.Fatalf("failed to create index, err: %v", err) 97 } 98 99 log.Printf(msgFmt, "start loading collection") 100 err = c.LoadCollection(ctx, collectionName, false) 101 if err != nil { 102 log.Fatalf("failed to load collection, err: %v", err) 103 } 104 105 log.Printf(msgFmt, "start searcching based on vector similarity") 106 vec2search := []entity.Vector{ 107 entity.FloatVector(embeddingList[len(embeddingList)-2]), 108 entity.FloatVector(embeddingList[len(embeddingList)-1]), 109 } 110 begin := time.Now() 111 sp, _ := entity.NewIndexIvfFlatSearchParam(16) 112 sRet, err := c.Search(ctx, collectionName, nil, "", []string{randomCol}, vec2search, 113 embeddingCol, entity.L2, topK, sp) 114 end := time.Now() 115 if err != nil { 116 log.Fatalf("failed to search collection, err: %v", err) 117 } 118 119 log.Println("results:") 120 for _, res := range sRet { 121 printResult(&res) 122 } 123 log.Printf("\tsearch latency: %dms\n", end.Sub(begin)/time.Millisecond) 124 125 // hybrid search 126 log.Printf(msgFmt, "start hybrid searching with `random > 0.5`") 127 begin = time.Now() 128 sRet2, err := c.Search(ctx, collectionName, nil, "random > 0.5", 129 []string{randomCol}, vec2search, embeddingCol, entity.L2, topK, sp) 130 end = time.Now() 131 if err != nil { 132 log.Fatalf("failed to search collection, err: %v", err) 133 } 134 log.Println("results:") 135 for _, res := range sRet2 { 136 printResult(&res) 137 } 138 log.Printf("\tsearch latency: %dms\n", end.Sub(begin)/time.Millisecond) 139 140 // delete data 141 log.Printf(msgFmt, "start deleting with expr ``") 142 pks := entity.NewColumnInt64(idCol, []int64{0, 1}) 143 sRet3, err := c.QueryByPks(ctx, collectionName, nil, pks, []string{randomCol}) 144 if err != nil { 145 log.Fatalf("failed to query result, err: %v", err) 146 } 147 log.Println("results:") 148 idlist := make([]int64, 0) 149 randList := make([]float64, 0) 150 151 for _, col := range sRet3 { 152 if col.Name() == idCol { 153 idColumn := col.(*entity.ColumnInt64) 154 for i := 0; i < col.Len(); i++ { 155 val, err := idColumn.ValueByIdx(i) 156 if err != nil { 157 log.Fatal(err) 158 } 159 idlist = append(idlist, val) 160 } 161 } else { 162 randColumn := col.(*entity.ColumnDouble) 163 for i := 0; i < col.Len(); i++ { 164 val, err := randColumn.ValueByIdx(i) 165 if err != nil { 166 log.Fatal(err) 167 } 168 randList = append(randList, val) 169 } 170 } 171 } 172 log.Printf("\tids: %#v, randoms: %#v\n", idlist, randList) 173 174 if err := c.DeleteByPks(ctx, collectionName, "", pks); err != nil { 175 log.Fatalf("failed to delete by pks, err: %v", err) 176 } 177 _, err = c.QueryByPks(ctx, collectionName, nil, pks, []string{randomCol}, client.WithSearchQueryConsistencyLevel(entity.ClStrong)) 178 if err != nil { 179 log.Printf("failed to query result, err: %v", err) 180 } 181 182 // drop collection 183 log.Printf(msgFmt, "drop collection `hello_milvus`") 184 if err := c.DropCollection(ctx, collectionName); err != nil { 185 log.Fatalf("failed to drop collection, err: %v", err) 186 } 187 } 188 189 func printResult(sRet *client.SearchResult) { 190 randoms := make([]float64, 0, sRet.ResultCount) 191 scores := make([]float32, 0, sRet.ResultCount) 192 193 var randCol *entity.ColumnDouble 194 for _, field := range sRet.Fields { 195 if field.Name() == randomCol { 196 c, ok := field.(*entity.ColumnDouble) 197 if ok { 198 randCol = c 199 } 200 } 201 } 202 for i := 0; i < sRet.ResultCount; i++ { 203 val, err := randCol.ValueByIdx(i) 204 if err != nil { 205 log.Fatal(err) 206 } 207 randoms = append(randoms, val) 208 scores = append(scores, sRet.Scores[i]) 209 } 210 log.Printf("\trandoms: %v, scores: %v\n", randoms, scores) 211 }