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  }