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