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  }