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 }