github.com/milvus-io/milvus-sdk-go/v2@v2.4.1/examples/tls/tls.go (about) 1 package main 2 3 import ( 4 "context" 5 "crypto/tls" 6 "crypto/x509" 7 "encoding/csv" 8 "fmt" 9 "log" 10 "os" 11 "strconv" 12 "strings" 13 "time" 14 15 "google.golang.org/grpc" 16 17 "github.com/milvus-io/milvus-sdk-go/v2/client" 18 "github.com/milvus-io/milvus-sdk-go/v2/entity" 19 "google.golang.org/grpc/credentials" 20 ) 21 22 func main() { 23 // Milvus instance proxy address, may verify in your env/settings 24 milvusAddr := `localhost:19530` 25 26 // setup context for client creation, use 2 seconds here 27 ctx := context.Background() 28 ctx, cancel := context.WithTimeout(ctx, 2*time.Second) 29 defer cancel() 30 31 // setup tls 32 cert, err := tls.LoadX509KeyPair("../cert/client.pem", "../cert/client.key") // 注意这里是 client 的证书 33 if err != nil { 34 log.Fatalf("tls.LoadX509KeyPair err: %v", err) 35 } 36 37 certPool := x509.NewCertPool() 38 ca, err := os.ReadFile("../cert/ca.pem") 39 if err != nil { 40 log.Fatalf("os.ReadFile err: %v", err) 41 } 42 43 if ok := certPool.AppendCertsFromPEM(ca); !ok { 44 log.Fatalf("certPool.AppendCertsFromPEM err") 45 } 46 47 creds := credentials.NewTLS(&tls.Config{ 48 Certificates: []tls.Certificate{cert}, 49 ServerName: "localhost", 50 RootCAs: certPool, 51 MinVersion: tls.VersionTLS13, 52 }) 53 54 c, err := client.NewClient(ctx, client.Config{ 55 Address: milvusAddr, 56 DialOptions: []grpc.DialOption{grpc.WithTransportCredentials(creds)}, 57 }) 58 if err != nil { 59 // handling error and exit, to make example simple here 60 log.Fatal("failed to connect to milvus:", err.Error()) 61 } 62 // in a main func, remember to close the client 63 defer c.Close() 64 65 // here is the collection name we use in this example 66 collectionName := `gosdk_insert_example` 67 68 has, err := c.HasCollection(ctx, collectionName) 69 if err != nil { 70 log.Fatal("failed to check whether collection exists:", err.Error()) 71 } 72 if has { 73 // collection with same name exist, clean up mess 74 _ = c.DropCollection(ctx, collectionName) 75 } 76 77 // define collection schema, see film.csv 78 schema := &entity.Schema{ 79 CollectionName: collectionName, 80 Description: "this is the example collection for inser and search", 81 AutoID: false, 82 Fields: []*entity.Field{ 83 { 84 Name: "ID", 85 DataType: entity.FieldTypeInt64, // int64 only for now 86 PrimaryKey: true, 87 AutoID: false, 88 }, 89 { 90 Name: "Year", 91 DataType: entity.FieldTypeInt32, 92 PrimaryKey: false, 93 AutoID: false, 94 }, 95 { 96 Name: "Vector", 97 DataType: entity.FieldTypeFloatVector, 98 TypeParams: map[string]string{ 99 entity.TypeParamDim: "8", 100 }, 101 }, 102 }, 103 } 104 105 err = c.CreateCollection(ctx, schema, entity.DefaultShardNumber) 106 if err != nil { 107 log.Fatal("failed to create collection:", err.Error()) 108 } 109 110 films, err := loadFilmCSV() 111 if err != nil { 112 log.Fatal("failed to load film data csv:", err.Error()) 113 } 114 115 // row-base covert to column-base 116 ids := make([]int64, 0, len(films)) 117 years := make([]int32, 0, len(films)) 118 vectors := make([][]float32, 0, len(films)) 119 // string field is not supported yet 120 idTitle := make(map[int64]string) 121 for idx, film := range films { 122 ids = append(ids, film.ID) 123 idTitle[film.ID] = film.Title 124 years = append(years, film.Year) 125 vectors = append(vectors, films[idx].Vector[:]) // prevent same vector 126 } 127 idColumn := entity.NewColumnInt64("ID", ids) 128 yearColumn := entity.NewColumnInt32("Year", years) 129 vectorColumn := entity.NewColumnFloatVector("Vector", 8, vectors) 130 131 // insert into default partition 132 _, err = c.Insert(ctx, collectionName, "", idColumn, yearColumn, vectorColumn) 133 if err != nil { 134 log.Fatal("failed to insert film data:", err.Error()) 135 } 136 log.Println("insert completed") 137 ctx, cancel = context.WithTimeout(context.Background(), time.Second*120) 138 defer cancel() 139 err = c.Flush(ctx, collectionName, false) 140 if err != nil { 141 log.Fatal("failed to flush collection:", err.Error()) 142 } 143 log.Println("flush completed") 144 145 // load collection with async=false 146 err = c.LoadCollection(ctx, collectionName, false) 147 if err != nil { 148 log.Fatal("failed to load collection:", err.Error()) 149 } 150 log.Println("load collection completed") 151 152 searchFilm := films[0] // use first fim to search 153 vector := entity.FloatVector(searchFilm.Vector[:]) 154 // Use flat search param 155 sp, _ := entity.NewIndexFlatSearchParam() 156 sr, err := c.Search(ctx, collectionName, []string{}, "Year > 1990", []string{"ID"}, []entity.Vector{vector}, "Vector", 157 entity.L2, 10, sp) 158 if err != nil { 159 log.Fatal("fail to search collection:", err.Error()) 160 } 161 for _, result := range sr { 162 var idColumn *entity.ColumnInt64 163 for _, field := range result.Fields { 164 if field.Name() == "ID" { 165 c, ok := field.(*entity.ColumnInt64) 166 if ok { 167 idColumn = c 168 } 169 } 170 } 171 if idColumn == nil { 172 log.Fatal("result field not math") 173 } 174 for i := 0; i < result.ResultCount; i++ { 175 id, err := idColumn.ValueByIdx(i) 176 if err != nil { 177 log.Fatal(err.Error()) 178 } 179 title := idTitle[id] 180 fmt.Printf("file id: %d title: %s scores: %f\n", id, title, result.Scores[i]) 181 } 182 } 183 184 // clean up 185 _ = c.DropCollection(ctx, collectionName) 186 } 187 188 type film struct { 189 ID int64 190 Title string 191 Year int32 192 Vector [8]float32 // fix length array 193 } 194 195 func loadFilmCSV() ([]film, error) { 196 f, err := os.Open("../films.csv") // assume you are in examples/insert folder, if not, please change the path 197 if err != nil { 198 return []film{}, err 199 } 200 r := csv.NewReader(f) 201 raw, err := r.ReadAll() 202 if err != nil { 203 return []film{}, err 204 } 205 films := make([]film, 0, len(raw)) 206 for _, line := range raw { 207 if len(line) < 4 { // insuffcient column 208 continue 209 } 210 fi := film{} 211 // ID 212 v, err := strconv.ParseInt(line[0], 10, 64) 213 if err != nil { 214 continue 215 } 216 fi.ID = v 217 // Title 218 fi.Title = line[1] 219 // Year 220 v, err = strconv.ParseInt(line[2], 10, 64) 221 if err != nil { 222 continue 223 } 224 fi.Year = int32(v) 225 // Vector 226 vectorStr := strings.ReplaceAll(line[3], "[", "") 227 vectorStr = strings.ReplaceAll(vectorStr, "]", "") 228 parts := strings.Split(vectorStr, ",") 229 if len(parts) != 8 { // dim must be 8 230 continue 231 } 232 for idx, part := range parts { 233 part = strings.TrimSpace(part) 234 v, err := strconv.ParseFloat(part, 32) 235 if err != nil { 236 continue 237 } 238 fi.Vector[idx] = float32(v) 239 } 240 films = append(films, fi) 241 } 242 return films, nil 243 }