github.com/milvus-io/milvus-sdk-go/v2@v2.4.1/test/testcases/index_test.go (about)

     1  //go:build L0
     2  
     3  package testcases
     4  
     5  import (
     6  	"fmt"
     7  	"log"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/milvus-io/milvus-sdk-go/v2/client"
    14  	"github.com/milvus-io/milvus-sdk-go/v2/entity"
    15  
    16  	"github.com/milvus-io/milvus-sdk-go/v2/test/common"
    17  )
    18  
    19  func supportScalarIndexFieldType(field entity.FieldType) bool {
    20  	vectorFieldTypes := []entity.FieldType{
    21  		entity.FieldTypeBinaryVector, entity.FieldTypeFloatVector,
    22  		entity.FieldTypeFloat16Vector, entity.FieldTypeBFloat16Vector,
    23  		entity.FieldTypeArray, entity.FieldTypeJSON,
    24  	}
    25  	for _, vectorFieldType := range vectorFieldTypes {
    26  		if field == vectorFieldType {
    27  			return false
    28  		}
    29  	}
    30  	return true
    31  }
    32  
    33  // test create index with supported float vector index, L2 metric type
    34  func TestCreateIndex(t *testing.T) {
    35  	t.Parallel()
    36  	ctx := createContext(t, time.Second*common.DefaultTimeout*5)
    37  	// connect
    38  	mc := createMilvusClient(ctx, t)
    39  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
    40  
    41  	// create index
    42  	allFloatIndexes := common.GenAllFloatIndex()
    43  	for _, idx := range allFloatIndexes {
    44  		// create default collection with flush data
    45  		err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false, client.WithIndexName(common.DefaultIndexName))
    46  		common.CheckErr(t, err, true)
    47  
    48  		// describe index
    49  		indexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultFloatVecFieldName)
    50  		expIndex := entity.NewGenericIndex(common.DefaultIndexName, idx.IndexType(), idx.Params())
    51  		common.CheckIndexResult(t, indexes, expIndex)
    52  
    53  		// drop index
    54  		err = mc.DropIndex(ctx, collName, common.DefaultFloatVecFieldName)
    55  		common.CheckErr(t, err, true)
    56  	}
    57  }
    58  
    59  // create index for fp16 and bf16 vectors
    60  func TestCreateIndexMultiVectors(t *testing.T) {
    61  	ctx := createContext(t, time.Second*common.DefaultTimeout*5)
    62  	// connect
    63  	mc := createMilvusClient(ctx, t)
    64  
    65  	// create collection
    66  	cp := CollectionParams{CollectionFieldsType: AllVectors, AutoID: false, EnableDynamicField: true, ShardsNum: 1,
    67  		Dim: common.DefaultDim}
    68  	collName := createCollection(ctx, t, mc, cp)
    69  
    70  	// insert
    71  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllVectors, start: 0,
    72  		nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true}
    73  	_, _ = insertData(ctx, t, mc, dp)
    74  	_ = mc.Flush(ctx, collName, false)
    75  
    76  	// create index for all vectors
    77  	idxHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
    78  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idxHnsw, false)
    79  	common.CheckErr(t, err, true)
    80  	for _, idx := range common.GenAllFloatIndex() {
    81  		for _, fieldName := range []string{common.DefaultFloat16VecFieldName, common.DefaultBFloat16VecFieldName} {
    82  			err := mc.CreateIndex(ctx, collName, fieldName, idx, false, client.WithIndexName(fieldName))
    83  			common.CheckErr(t, err, true)
    84  
    85  			// describe index
    86  			indexes, _ := mc.DescribeIndex(ctx, collName, fieldName)
    87  			expIndex := entity.NewGenericIndex(fieldName, idx.IndexType(), idx.Params())
    88  			common.CheckIndexResult(t, indexes, expIndex)
    89  
    90  			// drop index
    91  			err = mc.DropIndex(ctx, collName, fieldName, client.WithIndexName(fieldName))
    92  			common.CheckErr(t, err, true)
    93  		}
    94  	}
    95  	for _, metricType := range common.SupportBinIvfFlatMetricType {
    96  		idx, _ := entity.NewIndexBinFlat(metricType, 64)
    97  		err := mc.CreateIndex(ctx, collName, common.DefaultBinaryVecFieldName, idx, false, client.WithIndexName(common.DefaultBinaryVecFieldName))
    98  		common.CheckErr(t, err, true)
    99  
   100  		// drop index
   101  		err = mc.DropIndex(ctx, collName, common.DefaultBinaryVecFieldName, client.WithIndexName(common.DefaultBinaryVecFieldName))
   102  		common.CheckErr(t, err, true)
   103  	}
   104  }
   105  
   106  func TestDescribeIndexMultiVectors(t *testing.T) {
   107  	ctx := createContext(t, time.Second*common.DefaultTimeout*2)
   108  	// connect
   109  	mc := createMilvusClient(ctx, t)
   110  	// create -> insert [0, 3000) -> flush -> index -> load
   111  	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true,
   112  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   113  
   114  	dp := DataParams{DoInsert: true, CollectionFieldsType: AllFields, start: 0, nb: common.DefaultNb * 2,
   115  		dim: common.DefaultDim, EnableDynamicField: true}
   116  
   117  	// create index for all vector fields
   118  	ips := GenDefaultIndexParamsForAllVectors()
   119  
   120  	collName := prepareCollection(ctx, t, mc, cp, WithDataParams(dp), WithIndexParams(ips), WithCreateOption(client.WithConsistencyLevel(entity.ClStrong)))
   121  	for _, fieldName := range common.AllVectorsFieldsName {
   122  		indexes, err := mc.DescribeIndex(ctx, collName, fieldName)
   123  		common.CheckErr(t, err, true)
   124  		require.Len(t, indexes, 1)
   125  		for _, ip := range ips {
   126  			if ip.FieldName == fieldName {
   127  				expIndex := entity.NewGenericIndex(fieldName, ip.Index.IndexType(), ip.Index.Params())
   128  				common.CheckIndexResult(t, indexes, expIndex)
   129  			}
   130  		}
   131  	}
   132  }
   133  
   134  // test create index on same field twice
   135  func TestCreateIndexDup(t *testing.T) {
   136  	// create index
   137  	idxHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
   138  	idxIvfSq8, _ := entity.NewIndexIvfSQ8(entity.L2, 128)
   139  	ctx := createContext(t, time.Second*common.DefaultTimeout*3)
   140  	// connect
   141  	mc := createMilvusClient(ctx, t)
   142  	// create default collection with flush data
   143  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
   144  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idxHnsw, false)
   145  	common.CheckErr(t, err, true)
   146  
   147  	// describe index
   148  	indexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultFloatVecFieldName)
   149  	expIndex := entity.NewGenericIndex(common.DefaultFloatVecFieldName, idxHnsw.IndexType(), idxHnsw.Params())
   150  	common.CheckIndexResult(t, indexes, expIndex)
   151  
   152  	err = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idxIvfSq8, false)
   153  	common.CheckErr(t, err, false, "CreateIndex failed: at most one distinct index is allowed per field")
   154  }
   155  
   156  // test create scalar index on all scalar field
   157  func TestCreateScalarIndex(t *testing.T) {
   158  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   159  	//connect
   160  	mc := createMilvusClient(ctx, t)
   161  
   162  	// create collection with all datatype
   163  	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true,
   164  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   165  	collName := createCollection(ctx, t, mc, cp)
   166  
   167  	// insert
   168  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields,
   169  		start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   170  	_, _ = insertData(ctx, t, mc, dp)
   171  	mc.Flush(ctx, collName, false)
   172  
   173  	// create index for all vector fields
   174  	indexHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
   175  	indexBinary, _ := entity.NewIndexBinIvfFlat(entity.JACCARD, 64)
   176  	var expIndex entity.Index
   177  	var err error
   178  	for _, fieldName := range common.AllVectorsFieldsName {
   179  		if fieldName == common.DefaultBinaryVecFieldName {
   180  			err = mc.CreateIndex(ctx, collName, fieldName, indexBinary, false)
   181  			expIndex = entity.NewGenericIndex(fieldName, entity.BinIvfFlat, indexBinary.Params())
   182  		} else {
   183  			err = mc.CreateIndex(ctx, collName, fieldName, indexHnsw, false)
   184  			expIndex = entity.NewGenericIndex(fieldName, entity.HNSW, indexHnsw.Params())
   185  		}
   186  		common.CheckErr(t, err, true)
   187  		indexes, _ := mc.DescribeIndex(ctx, collName, fieldName)
   188  		common.CheckIndexResult(t, indexes, expIndex)
   189  	}
   190  
   191  	coll, _ := mc.DescribeCollection(ctx, collName)
   192  	idx := entity.NewScalarIndex()
   193  	for _, field := range coll.Schema.Fields {
   194  		if supportScalarIndexFieldType(field.DataType) {
   195  			err := mc.CreateIndex(ctx, collName, field.Name, idx, false, client.WithIndexName(field.Name))
   196  			common.CheckErr(t, err, true)
   197  
   198  			// describe index
   199  			indexes, _ := mc.DescribeIndex(ctx, collName, field.Name)
   200  			expIndex := entity.NewGenericIndex(field.Name, "", idx.Params())
   201  			common.CheckIndexResult(t, indexes, expIndex)
   202  		}
   203  	}
   204  	// load -> search and output all fields
   205  	err = mc.LoadCollection(ctx, collName, false)
   206  	common.CheckErr(t, err, true)
   207  	queryVec := common.GenSearchVectors(common.DefaultNq, common.DefaultDim, entity.FieldTypeFloatVector)
   208  	sp, _ := entity.NewIndexHNSWSearchParam(74)
   209  	searchRes, _ := mc.Search(ctx, collName, []string{}, "", []string{"*"}, queryVec, common.DefaultFloatVecFieldName,
   210  		entity.L2, common.DefaultTopK, sp)
   211  	common.CheckOutputFields(t, searchRes[0].Fields, common.GetAllFieldsName(true, false))
   212  }
   213  
   214  // Trie scalar index only supported on varchar
   215  func TestCreateTrieScalarIndexUnsupportedDataType(t *testing.T) {
   216  	ctx := createContext(t, time.Second*common.DefaultTimeout*2)
   217  	// connect
   218  	mc := createMilvusClient(ctx, t)
   219  
   220  	// create -> insert [0, 3000) -> flush -> index -> load
   221  	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: false,
   222  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   223  
   224  	dp := DataParams{DoInsert: true, CollectionFieldsType: AllFields, start: 0, nb: common.DefaultNb,
   225  		dim: common.DefaultDim, EnableDynamicField: false}
   226  
   227  	// index params
   228  	ips := []IndexParams{{BuildIndex: false}}
   229  	lp := LoadParams{DoLoad: false}
   230  	collName := prepareCollection(ctx, t, mc, cp, WithDataParams(dp), WithIndexParams(ips), WithLoadParams(lp),
   231  		WithCreateOption(client.WithConsistencyLevel(entity.ClStrong)))
   232  
   233  	// create Trie scalar index on varchar field
   234  	coll, _ := mc.DescribeCollection(ctx, collName)
   235  	idx := entity.NewScalarIndexWithType(entity.Trie)
   236  	for _, field := range coll.Schema.Fields {
   237  		if supportScalarIndexFieldType(field.DataType) {
   238  			if field.DataType == entity.FieldTypeVarChar {
   239  				err := mc.CreateIndex(ctx, collName, field.Name, idx, false, client.WithIndexName(field.Name))
   240  				common.CheckErr(t, err, true)
   241  
   242  				// describe index
   243  				indexes, _ := mc.DescribeIndex(ctx, collName, field.Name)
   244  				expIndex := entity.NewGenericIndex(field.Name, entity.Trie, idx.Params())
   245  				common.CheckIndexResult(t, indexes, expIndex)
   246  			} else {
   247  				err := mc.CreateIndex(ctx, collName, field.Name, idx, false, client.WithIndexName(field.Name))
   248  				common.CheckErr(t, err, false, "TRIE are only supported on varchar field")
   249  			}
   250  		}
   251  	}
   252  }
   253  
   254  // Sort scalar index only supported on numeric field
   255  func TestCreateSortScalarIndexUnsupportedDataType(t *testing.T) {
   256  	ctx := createContext(t, time.Second*common.DefaultTimeout*2)
   257  	// connect
   258  	mc := createMilvusClient(ctx, t)
   259  
   260  	// create -> insert [0, 3000) -> flush -> index -> load
   261  	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: false,
   262  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   263  
   264  	dp := DataParams{DoInsert: true, CollectionFieldsType: AllFields, start: 0, nb: common.DefaultNb,
   265  		dim: common.DefaultDim, EnableDynamicField: false}
   266  
   267  	// index params
   268  	ips := []IndexParams{{BuildIndex: false}}
   269  	lp := LoadParams{DoLoad: false}
   270  	collName := prepareCollection(ctx, t, mc, cp, WithDataParams(dp), WithIndexParams(ips), WithLoadParams(lp),
   271  		WithCreateOption(client.WithConsistencyLevel(entity.ClStrong)))
   272  
   273  	// create Trie scalar index on varchar field
   274  	coll, _ := mc.DescribeCollection(ctx, collName)
   275  	idx := entity.NewScalarIndexWithType(entity.Sorted)
   276  	for _, field := range coll.Schema.Fields {
   277  		if supportScalarIndexFieldType(field.DataType) {
   278  			if field.DataType == entity.FieldTypeVarChar || field.DataType == entity.FieldTypeBool {
   279  				err := mc.CreateIndex(ctx, collName, field.Name, idx, false, client.WithIndexName(field.Name))
   280  				common.CheckErr(t, err, false, "STL_SORT are only supported on numeric field")
   281  			} else {
   282  				log.Println(field.Name, field.DataType)
   283  				err := mc.CreateIndex(ctx, collName, field.Name, idx, false, client.WithIndexName(field.Name))
   284  				common.CheckErr(t, err, true)
   285  				// describe index
   286  				indexes, _ := mc.DescribeIndex(ctx, collName, field.Name)
   287  				expIndex := entity.NewGenericIndex(field.Name, entity.Sorted, idx.Params())
   288  				common.CheckIndexResult(t, indexes, expIndex)
   289  			}
   290  		}
   291  	}
   292  }
   293  
   294  // create Inverted index for all scalar fields
   295  func TestCreateInvertedScalarIndex(t *testing.T) {
   296  	ctx := createContext(t, time.Second*common.DefaultTimeout*2)
   297  	// connect
   298  	mc := createMilvusClient(ctx, t)
   299  
   300  	// create -> insert [0, 3000) -> flush -> index -> load
   301  	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: false,
   302  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   303  
   304  	dp := DataParams{DoInsert: true, CollectionFieldsType: AllFields, start: 0, nb: common.DefaultNb,
   305  		dim: common.DefaultDim, EnableDynamicField: false}
   306  
   307  	// index params
   308  	ips := GenDefaultIndexParamsForAllVectors()
   309  	lp := LoadParams{DoLoad: false}
   310  	collName := prepareCollection(ctx, t, mc, cp, WithDataParams(dp), WithIndexParams(ips), WithLoadParams(lp),
   311  		WithCreateOption(client.WithConsistencyLevel(entity.ClStrong)))
   312  
   313  	// create Trie scalar index on varchar field
   314  	coll, _ := mc.DescribeCollection(ctx, collName)
   315  	idx := entity.NewScalarIndexWithType(entity.Inverted)
   316  	for _, field := range coll.Schema.Fields {
   317  		if supportScalarIndexFieldType(field.DataType) {
   318  			err := mc.CreateIndex(ctx, collName, field.Name, idx, false, client.WithIndexName(field.Name))
   319  			common.CheckErr(t, err, true)
   320  
   321  			// describe index
   322  			indexes, _ := mc.DescribeIndex(ctx, collName, field.Name)
   323  			require.Len(t, indexes, 1)
   324  			log.Println(indexes[0].Name(), indexes[0].IndexType(), indexes[0].Params())
   325  			expIndex := entity.NewGenericIndex(field.Name, entity.Inverted, idx.Params())
   326  			common.CheckIndexResult(t, indexes, expIndex)
   327  		}
   328  	}
   329  	// load -> search and output all fields
   330  	err := mc.LoadCollection(ctx, collName, false)
   331  	common.CheckErr(t, err, true)
   332  	queryVec := common.GenSearchVectors(common.DefaultNq, common.DefaultDim, entity.FieldTypeFloatVector)
   333  	sp, _ := entity.NewIndexHNSWSearchParam(74)
   334  	expr := fmt.Sprintf("%s > 10", common.DefaultIntFieldName)
   335  	searchRes, _ := mc.Search(ctx, collName, []string{}, expr, []string{"*"}, queryVec, common.DefaultFloatVecFieldName,
   336  		entity.L2, common.DefaultTopK, sp)
   337  	common.CheckOutputFields(t, searchRes[0].Fields, common.GetAllFieldsName(false, false))
   338  }
   339  
   340  // test create index on vector field
   341  func TestCreateScalarIndexVectorField(t *testing.T) {
   342  	ctx := createContext(t, time.Second*common.DefaultTimeout*2)
   343  	// connect
   344  	mc := createMilvusClient(ctx, t)
   345  
   346  	// create -> insert [0, 3000) -> flush -> index -> load
   347  	cp := CollectionParams{CollectionFieldsType: AllVectors, AutoID: false, EnableDynamicField: false,
   348  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   349  
   350  	dp := DataParams{DoInsert: true, CollectionFieldsType: AllVectors, start: 0, nb: common.DefaultNb,
   351  		dim: common.DefaultDim, EnableDynamicField: false}
   352  
   353  	// no index
   354  	ips := []IndexParams{{BuildIndex: false}}
   355  	lp := LoadParams{DoLoad: false}
   356  	collName := prepareCollection(ctx, t, mc, cp, WithDataParams(dp), WithIndexParams(ips), WithLoadParams(lp),
   357  		WithCreateOption(client.WithConsistencyLevel(entity.ClStrong)))
   358  
   359  	for _, ip := range []entity.IndexType{entity.Sorted, entity.Trie, entity.Inverted} {
   360  		idx := entity.NewScalarIndexWithType(ip)
   361  		for _, fieldName := range common.AllVectorsFieldsName {
   362  			err := mc.CreateIndex(ctx, collName, fieldName, idx, false)
   363  			common.CheckErr(t, err, false, "STL_SORT are only supported on numeric field",
   364  				"TRIE are only supported on varchar field", "INVERTED are not supported on")
   365  		}
   366  	}
   367  	for _, fieldName := range common.AllFloatVectorsFieldNames {
   368  		idxDefault := entity.NewScalarIndex()
   369  		err := mc.CreateIndex(ctx, collName, fieldName, idxDefault, false)
   370  		common.CheckErr(t, err, true)
   371  		descIndex, _ := mc.DescribeIndex(ctx, collName, fieldName)
   372  		require.Equal(t, entity.AUTOINDEX, descIndex[0].IndexType())
   373  	}
   374  }
   375  
   376  // test create scalar index with vector field name
   377  func TestCreateIndexWithOtherFieldName(t *testing.T) {
   378  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   379  	//connect
   380  	mc := createMilvusClient(ctx, t)
   381  
   382  	collName, _ := createVarcharCollectionWithDataIndex(ctx, t, mc, false)
   383  	idx := entity.NewScalarIndex()
   384  	// create index with vector field name as index name (vector field name is the vector default index name)
   385  	err := mc.CreateIndex(ctx, collName, common.DefaultVarcharFieldName, idx, false,
   386  		client.WithIndexName(common.DefaultBinaryVecFieldName))
   387  	common.CheckErr(t, err, true)
   388  
   389  	// describe index
   390  	indexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultVarcharFieldName)
   391  	expIndex := entity.NewGenericIndex(common.DefaultBinaryVecFieldName, "", idx.Params())
   392  	common.CheckIndexResult(t, indexes, expIndex)
   393  
   394  	// create index in binary field with default name
   395  	idxBinary, _ := entity.NewIndexBinFlat(entity.JACCARD, 64)
   396  	err = mc.CreateIndex(ctx, collName, common.DefaultBinaryVecFieldName, idxBinary, false)
   397  	common.CheckErr(t, err, false, "CreateIndex failed: at most one distinct index is allowed per field")
   398  }
   399  
   400  func TestCreateIndexJsonField(t *testing.T) {
   401  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   402  	// connect
   403  	mc := createMilvusClient(ctx, t)
   404  
   405  	// create collection
   406  	cp := CollectionParams{CollectionFieldsType: Int64FloatVecJSON, AutoID: false, EnableDynamicField: false,
   407  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   408  	collName := createCollection(ctx, t, mc, cp)
   409  
   410  	// insert
   411  	dp := DataParams{CollectionName: collName, CollectionFieldsType: Int64FloatVecJSON, start: 0, nb: common.DefaultNb,
   412  		dim: common.DefaultDim, EnableDynamicField: false}
   413  	_, _ = insertData(ctx, t, mc, dp)
   414  
   415  	// create vector index on json field
   416  	idx, _ := entity.NewIndexSCANN(entity.L2, 8, false)
   417  	err := mc.CreateIndex(ctx, collName, common.DefaultJSONFieldName, idx, false, client.WithIndexName("json_index"))
   418  	common.CheckErr(t, err, false, "data type should be FloatVector, Float16Vector or BFloat16Vector")
   419  
   420  	//create scalar index on json field
   421  	type scalarIndexError struct {
   422  		indexType entity.IndexType
   423  		errMsg    string
   424  	}
   425  	inxError := []scalarIndexError{
   426  		{entity.Inverted, "INVERTED are not supported on JSON field"},
   427  		{entity.Sorted, "STL_SORT are only supported on numeric field"},
   428  		{entity.Trie, "TRIE are only supported on varchar field"},
   429  		{entity.Scalar, "create auto index on JSON field is not supported"},
   430  	}
   431  	for _, ip := range inxError {
   432  		err := mc.CreateIndex(ctx, collName, common.DefaultJSONFieldName, entity.NewScalarIndexWithType(ip.indexType), false, client.WithIndexName("json_index"))
   433  		common.CheckErr(t, err, false, ip.errMsg)
   434  	}
   435  }
   436  
   437  func TestCreateIndexArrayField(t *testing.T) {
   438  	t.Skip("array index supported")
   439  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   440  	// connect
   441  	mc := createMilvusClient(ctx, t)
   442  
   443  	// create collection
   444  	cp := CollectionParams{CollectionFieldsType: Int64FloatVecArray, AutoID: false, EnableDynamicField: true,
   445  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxCapacity: common.TestCapacity}
   446  	collName := createCollection(ctx, t, mc, cp)
   447  
   448  	// prepare and insert data
   449  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVecArray,
   450  		start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   451  	_, _ = insertData(ctx, t, mc, dp, common.WithArrayCapacity(common.TestCapacity))
   452  
   453  	// flush and check row count
   454  	errFlush := mc.Flush(ctx, collName, false)
   455  	common.CheckErr(t, errFlush, true)
   456  
   457  	type scalarIndexError struct {
   458  		indexType entity.IndexType
   459  		errMsg    string
   460  	}
   461  	inxError := []scalarIndexError{
   462  		{entity.Inverted, "INVERTED are not supported on Array field"},
   463  		{entity.Sorted, "STL_SORT are only supported on numeric field"},
   464  		{entity.Trie, "TRIE are only supported on varchar field"},
   465  		{entity.Scalar, "create auto index on Array field is not supported"},
   466  	}
   467  
   468  	// create scalar and vector index on array field
   469  	vectorIdx, _ := entity.NewIndexSCANN(entity.L2, 10, false)
   470  	for _, ip := range inxError {
   471  		scalarIdx := entity.NewScalarIndexWithType(ip.indexType)
   472  		collection, _ := mc.DescribeCollection(ctx, collName)
   473  		for _, field := range collection.Schema.Fields {
   474  			if field.DataType == entity.FieldTypeArray {
   475  				// create scalar index
   476  				err := mc.CreateIndex(ctx, collName, field.Name, scalarIdx, false, client.WithIndexName("scalar_index"))
   477  				common.CheckErr(t, err, false, ip.errMsg)
   478  				// create vector index
   479  				err1 := mc.CreateIndex(ctx, collName, field.Name, vectorIdx, false, client.WithIndexName("vector_index"))
   480  				common.CheckErr(t, err1, false, "data type should be FloatVector, Float16Vector or BFloat16Vector")
   481  			}
   482  		}
   483  	}
   484  }
   485  
   486  // test create index with supported binary vector index
   487  func TestCreateIndexBinaryFlat(t *testing.T) {
   488  	t.Parallel()
   489  
   490  	// create index
   491  	for _, metricType := range common.SupportBinFlatMetricType {
   492  		idx, _ := entity.NewIndexBinFlat(metricType, 128)
   493  		ctx := createContext(t, time.Second*common.DefaultTimeout)
   494  		// connect
   495  		mc := createMilvusClient(ctx, t)
   496  
   497  		// create default collection with flush data
   498  		collName, _ := createBinaryCollectionWithDataIndex(ctx, t, mc, false, false)
   499  		err := mc.CreateIndex(ctx, collName, common.DefaultBinaryVecFieldName, idx, false, client.WithIndexName("my_index"))
   500  		common.CheckErr(t, err, true)
   501  
   502  		// describe index
   503  		indexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultBinaryVecFieldName)
   504  		expIndex := entity.NewGenericIndex("my_index", idx.IndexType(), idx.Params())
   505  		common.CheckIndexResult(t, indexes, expIndex)
   506  	}
   507  }
   508  
   509  // test create index with supported binary vector index
   510  func TestCreateIndexBinaryIvfFlat(t *testing.T) {
   511  	t.Parallel()
   512  
   513  	// create index
   514  	for _, metricType := range common.SupportBinIvfFlatMetricType {
   515  		idx, _ := entity.NewIndexBinIvfFlat(metricType, 128)
   516  		ctx := createContext(t, time.Second*common.DefaultTimeout)
   517  		// connect
   518  		mc := createMilvusClient(ctx, t)
   519  
   520  		// create default collection with flush data
   521  		collName, _ := createBinaryCollectionWithDataIndex(ctx, t, mc, false, false)
   522  		err := mc.CreateIndex(ctx, collName, common.DefaultBinaryVecFieldName, idx, false, client.WithIndexName("my_index"))
   523  		common.CheckErr(t, err, true)
   524  
   525  		// describe index
   526  		indexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultBinaryVecFieldName)
   527  		expIndex := entity.NewGenericIndex("my_index", idx.IndexType(), idx.Params())
   528  		common.CheckIndexResult(t, indexes, expIndex)
   529  	}
   530  }
   531  
   532  // test create binary index with unsupported metrics type
   533  func TestCreateBinaryIndexNotSupportedMetricsType(t *testing.T) {
   534  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   535  	// connect
   536  	mc := createMilvusClient(ctx, t)
   537  	collName, _ := createBinaryCollectionWithDataIndex(ctx, t, mc, false, false)
   538  
   539  	// create BinIvfFlat, BinFlat index with not supported metric type
   540  	invalidMetricTypes := []entity.MetricType{
   541  		entity.L2,
   542  		entity.COSINE,
   543  		entity.IP,
   544  		entity.TANIMOTO,
   545  	}
   546  	for _, metricType := range invalidMetricTypes {
   547  		// create BinFlat
   548  		idxBinFlat, _ := entity.NewIndexBinFlat(metricType, 128)
   549  		err := mc.CreateIndex(ctx, collName, common.DefaultBinaryVecFieldName, idxBinFlat, false, client.WithIndexName("my_index"))
   550  		common.CheckErr(t, err, false, "supported: [HAMMING JACCARD SUBSTRUCTURE SUPERSTRUCTURE]")
   551  	}
   552  
   553  	invalidMetricTypes2 := []entity.MetricType{
   554  		entity.L2,
   555  		entity.COSINE,
   556  		entity.IP,
   557  		entity.TANIMOTO,
   558  		entity.SUBSTRUCTURE,
   559  		entity.SUPERSTRUCTURE,
   560  	}
   561  
   562  	for _, metricType := range invalidMetricTypes2 {
   563  		// create BinIvfFlat index
   564  		idxBinIvfFlat, _ := entity.NewIndexBinIvfFlat(metricType, 128)
   565  		errIvf := mc.CreateIndex(ctx, collName, common.DefaultBinaryVecFieldName, idxBinIvfFlat, false, client.WithIndexName("my_index2"))
   566  		common.CheckErr(t, errIvf, false, fmt.Sprintf("metric type %v not found or not supported", metricType))
   567  	}
   568  
   569  }
   570  
   571  // test create index without specify index name
   572  func TestCreateIndexWithoutName(t *testing.T) {
   573  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   574  	// connect
   575  	mc := createMilvusClient(ctx, t)
   576  
   577  	// create default collection with flush data
   578  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
   579  
   580  	// create index
   581  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
   582  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false)
   583  	common.CheckErr(t, err, true)
   584  
   585  	// describe index return index with default name
   586  	indexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultFloatVecFieldName)
   587  	expIndex := entity.NewGenericIndex(common.DefaultFloatVecFieldName, idx.IndexType(), idx.Params())
   588  	common.CheckIndexResult(t, indexes, expIndex)
   589  }
   590  
   591  // test create auto index
   592  func TestCreateIndexWithoutIndexTypeParams(t *testing.T) {
   593  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   594  	//connect
   595  	mc := createMilvusClient(ctx, t)
   596  
   597  	// create collection with all datatype
   598  	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true,
   599  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   600  	collName := createCollection(ctx, t, mc, cp)
   601  
   602  	// insert
   603  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields,
   604  		start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   605  	_, _ = insertData(ctx, t, mc, dp)
   606  	err := mc.Flush(ctx, collName, false)
   607  	common.CheckErr(t, err, true)
   608  
   609  	for _, fieldName := range common.AllVectorsFieldsName {
   610  		idx, _ := entity.NewIndexAUTOINDEX(entity.COSINE)
   611  		if fieldName == common.DefaultBinaryVecFieldName {
   612  			err = mc.CreateIndex(ctx, collName, fieldName, idx, false)
   613  			common.CheckErr(t, err, false, "HNSW only support float vector data type")
   614  			// create binary index
   615  			idxBinary, _ := entity.NewIndexBinIvfFlat(entity.JACCARD, 64)
   616  			err = mc.CreateIndex(ctx, collName, fieldName, idxBinary, false)
   617  			common.CheckErr(t, err, true)
   618  		} else {
   619  			// create index
   620  			err = mc.CreateIndex(ctx, collName, fieldName, idx, false)
   621  			common.CheckErr(t, err, true)
   622  
   623  			// describe index
   624  			indexes, _ := mc.DescribeIndex(ctx, collName, fieldName)
   625  			expParams := map[string]string{
   626  				"metric_type": string(entity.COSINE),
   627  				"index_type":  string(entity.AUTOINDEX),
   628  			}
   629  			expIndex := entity.NewGenericIndex(fieldName, entity.AUTOINDEX, expParams)
   630  			common.CheckIndexResult(t, indexes, expIndex)
   631  		}
   632  	}
   633  
   634  	// load -> search and output all vector fields
   635  	err = mc.LoadCollection(ctx, collName, false)
   636  	common.CheckErr(t, err, true)
   637  	queryVec := common.GenSearchVectors(common.DefaultNq, common.DefaultDim, entity.FieldTypeFloatVector)
   638  	sp, _ := entity.NewIndexAUTOINDEXSearchParam(1)
   639  	searchRes, _ := mc.Search(ctx, collName, []string{}, "", common.AllVectorsFieldsName, queryVec, common.DefaultFloatVecFieldName,
   640  		entity.COSINE, common.DefaultTopK, sp)
   641  	common.CheckOutputFields(t, searchRes[0].Fields, common.AllVectorsFieldsName)
   642  }
   643  
   644  // test create default auto index on scalar fields -> error
   645  func TestCreateAutoIndexScalarFields(t *testing.T) {
   646  	t.Skip("https://github.com/milvus-io/milvus-sdk-go/issues/702")
   647  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   648  	//connect
   649  	mc := createMilvusClient(ctx, t)
   650  
   651  	// create collection with all datatype
   652  	cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true,
   653  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
   654  	collName := createCollection(ctx, t, mc, cp)
   655  
   656  	// insert
   657  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields,
   658  		start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   659  	_, _ = insertData(ctx, t, mc, dp)
   660  	mc.Flush(ctx, collName, false)
   661  
   662  	// create index for all vector fields
   663  	indexAuto, _ := entity.NewIndexAUTOINDEX(entity.L2)
   664  	coll, _ := mc.DescribeCollection(ctx, collName)
   665  	for _, field := range coll.Schema.Fields {
   666  		if supportScalarIndexFieldType(field.DataType) {
   667  			log.Println(field.Name, field.DataType)
   668  			err := mc.CreateIndex(ctx, collName, field.Name, indexAuto, false, client.WithIndexName(field.Name))
   669  			common.CheckErr(t, err, false, "HNSW only support float vector data type")
   670  		}
   671  	}
   672  }
   673  
   674  // TODO https://github.com/milvus-io/milvus-sdk-go/issues/726
   675  func TestCreateIndexSparseVector(t *testing.T) {
   676  	t.Parallel()
   677  	idxInverted := entity.NewGenericIndex(common.DefaultSparseVecFieldName, "SPARSE_INVERTED_INDEX", map[string]string{"drop_ratio_build": "0.2", "metric_type": "IP"})
   678  	idxWand := entity.NewGenericIndex(common.DefaultSparseVecFieldName, "SPARSE_WAND", map[string]string{"drop_ratio_build": "0.3", "metric_type": "IP"})
   679  
   680  	for _, idx := range []entity.Index{idxInverted, idxWand} {
   681  		ctx := createContext(t, time.Second*common.DefaultTimeout)
   682  		//connect
   683  		mc := createMilvusClient(ctx, t)
   684  
   685  		// create collection with all datatype
   686  		cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true,
   687  			ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: 300}
   688  		collName := createCollection(ctx, t, mc, cp)
   689  
   690  		// insert
   691  		dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64VarcharSparseVec,
   692  			start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   693  		_, _ = insertData(ctx, t, mc, dp, common.WithSparseVectorLen(100))
   694  		mc.Flush(ctx, collName, false)
   695  
   696  		// create index
   697  		err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   698  		common.CheckErr(t, err, true)
   699  
   700  		// describe index
   701  		idx2, err := mc.DescribeIndex(ctx, collName, common.DefaultSparseVecFieldName)
   702  		common.CheckErr(t, err, true)
   703  		common.CheckIndexResult(t, idx2, idx)
   704  	}
   705  }
   706  
   707  // TODO https://github.com/milvus-io/milvus-sdk-go/issues/726
   708  func TestCreateIndexSparseVector2(t *testing.T) {
   709  	t.Parallel()
   710  	idxInverted1, _ := entity.NewIndexSparseInverted(entity.IP, 0.2)
   711  	idxWand1, _ := entity.NewIndexSparseWAND(entity.IP, 0.3)
   712  	for _, idx := range []entity.Index{idxInverted1, idxWand1} {
   713  		ctx := createContext(t, time.Second*common.DefaultTimeout)
   714  		//connect
   715  		mc := createMilvusClient(ctx, t)
   716  
   717  		// create collection with all datatype
   718  		cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true,
   719  			ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: 300}
   720  		collName := createCollection(ctx, t, mc, cp)
   721  
   722  		// insert
   723  		dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64VarcharSparseVec,
   724  			start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   725  		_, _ = insertData(ctx, t, mc, dp, common.WithSparseVectorLen(100))
   726  		mc.Flush(ctx, collName, false)
   727  
   728  		// create index
   729  		err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   730  		common.CheckErr(t, err, true)
   731  
   732  		// describe index
   733  		idx2, err := mc.DescribeIndex(ctx, collName, common.DefaultSparseVecFieldName)
   734  		expIndex := entity.NewGenericIndex(common.DefaultSparseVecFieldName, idx.IndexType(), idx.Params())
   735  		common.CheckErr(t, err, true)
   736  		common.CheckIndexResult(t, idx2, expIndex)
   737  	}
   738  }
   739  
   740  // create index on sparse vector with invalid params
   741  func TestCreateSparseIndexInvalidParams(t *testing.T) {
   742  	for _, indexType := range []entity.IndexType{"SPARSE_INVERTED_INDEX", "SPARSE_WAND"} {
   743  		ctx := createContext(t, time.Second*common.DefaultTimeout)
   744  		//connect
   745  		mc := createMilvusClient(ctx, t)
   746  
   747  		// create collection with all datatype
   748  		cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true,
   749  			ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: 300}
   750  		collName := createCollection(ctx, t, mc, cp)
   751  
   752  		// insert
   753  		dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64VarcharSparseVec,
   754  			start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   755  		_, _ = insertData(ctx, t, mc, dp, common.WithSparseVectorLen(100))
   756  		mc.Flush(ctx, collName, false)
   757  
   758  		// create index with invalid metric type
   759  		for _, mt := range common.UnsupportedSparseVecMetricsType {
   760  			idx := entity.NewGenericIndex(common.DefaultSparseVecFieldName, indexType, map[string]string{"drop_ratio_build": "0.2", "metric_type": string(mt)})
   761  			err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   762  			common.CheckErr(t, err, false, "only IP is the supported metric type for sparse index")
   763  		}
   764  
   765  		// create index with invalid drop_ratio_build
   766  		for _, drb := range []string{"a", "-0.1", "1.3"} {
   767  			idx := entity.NewGenericIndex(common.DefaultSparseVecFieldName, indexType, map[string]string{"drop_ratio_build": drb, "metric_type": "IP"})
   768  			err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   769  			common.CheckErr(t, err, false, "must be in range [0, 1)")
   770  		}
   771  
   772  		// create index and describe index
   773  		idx := entity.NewGenericIndex(common.DefaultSparseVecFieldName, indexType, map[string]string{"drop_ratio_build": "0", "metric_type": "IP"})
   774  		err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   775  		common.CheckErr(t, err, true)
   776  
   777  		descIdx, _ := mc.DescribeIndex(ctx, collName, common.DefaultSparseVecFieldName)
   778  		common.CheckIndexResult(t, descIdx, idx)
   779  	}
   780  }
   781  
   782  func TestCreateSparseIndexInvalidParams2(t *testing.T) {
   783  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   784  	//connect
   785  	mc := createMilvusClient(ctx, t)
   786  
   787  	// create collection with all datatype
   788  	cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true,
   789  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: 300}
   790  	collName := createCollection(ctx, t, mc, cp)
   791  
   792  	// insert
   793  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64VarcharSparseVec,
   794  		start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   795  	_, _ = insertData(ctx, t, mc, dp, common.WithSparseVectorLen(100))
   796  	mc.Flush(ctx, collName, false)
   797  
   798  	// create index with invalid metric type
   799  	for _, mt := range common.UnsupportedSparseVecMetricsType {
   800  		idx, _ := entity.NewIndexSparseInverted(mt, 0.2)
   801  		err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   802  		common.CheckErr(t, err, false, "only IP is the supported metric type for sparse index")
   803  
   804  		idxWand, _ := entity.NewIndexSparseWAND(mt, 0.2)
   805  		err = mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idxWand, false)
   806  		common.CheckErr(t, err, false, "only IP is the supported metric type for sparse index")
   807  	}
   808  
   809  	// create index with invalid drop_ratio_build
   810  	for _, drb := range []float64{-0.3, 1.3} {
   811  		_, err := entity.NewIndexSparseInverted(entity.IP, drb)
   812  		common.CheckErr(t, err, false, "must be in range [0, 1)")
   813  
   814  		_, err = entity.NewIndexSparseWAND(entity.IP, drb)
   815  		common.CheckErr(t, err, false, "must be in range [0, 1)")
   816  	}
   817  
   818  	// create index and describe index
   819  	idx, _ := entity.NewIndexSparseInverted(entity.IP, 0.1)
   820  	err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   821  	common.CheckErr(t, err, true)
   822  
   823  	descIdx, _ := mc.DescribeIndex(ctx, collName, common.DefaultSparseVecFieldName)
   824  	expIdx := entity.NewGenericIndex(common.DefaultSparseVecFieldName, idx.IndexType(), idx.Params())
   825  	common.CheckIndexResult(t, descIdx, expIdx)
   826  }
   827  
   828  // create sparse unsupported index: other vector index and scalar index and auto index
   829  func TestCreateSparseUnsupportedIndex(t *testing.T) {
   830  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   831  	//connect
   832  	mc := createMilvusClient(ctx, t)
   833  
   834  	// create collection with all datatype
   835  	cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true,
   836  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: 300}
   837  	collName := createCollection(ctx, t, mc, cp)
   838  
   839  	// insert
   840  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64VarcharSparseVec,
   841  		start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
   842  	_, _ = insertData(ctx, t, mc, dp, common.WithSparseVectorLen(100))
   843  	mc.Flush(ctx, collName, false)
   844  
   845  	// create unsupported vector index on sparse field
   846  	autoIdx, _ := entity.NewIndexAUTOINDEX(entity.IP)
   847  	vectorIndex := append(common.GenAllFloatIndex(entity.IP), autoIdx)
   848  	for _, idx := range vectorIndex {
   849  		err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   850  		common.CheckErr(t, err, false, "data type should be FloatVector, Float16Vector or BFloat16Vector",
   851  			"HNSW only support float vector data type")
   852  	}
   853  
   854  	// create scalar index on sparse vector
   855  	for _, idx := range []entity.Index{
   856  		entity.NewScalarIndex(),
   857  		entity.NewScalarIndexWithType(entity.Trie),
   858  		entity.NewScalarIndexWithType(entity.Sorted),
   859  		entity.NewScalarIndexWithType(entity.Inverted),
   860  	} {
   861  		err := mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false)
   862  		common.CheckErr(t, err, false, "TRIE are only supported on varchar field",
   863  			"STL_SORT are only supported on numeric field", "HNSW only support float vector data type",
   864  			"INVERTED are not supported on SparseFloatVector field")
   865  	}
   866  }
   867  
   868  // test new index by Generic index
   869  func TestCreateIndexGeneric(t *testing.T) {
   870  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   871  	// connect
   872  	mc := createMilvusClient(ctx, t)
   873  
   874  	// create default collection with flush data
   875  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
   876  
   877  	// create index
   878  	IvfFlatParams := map[string]string{"nlist": "128", "metric_type": "L2"}
   879  	idx := entity.NewGenericIndex("my_index", entity.IvfFlat, IvfFlatParams)
   880  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false)
   881  	common.CheckErr(t, err, true)
   882  
   883  	// describe index
   884  	indexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultFloatVecFieldName)
   885  	expIndex := entity.NewGenericIndex(common.DefaultFloatVecFieldName, idx.IndexType(), idx.Params())
   886  	common.CheckIndexResult(t, indexes, expIndex)
   887  }
   888  
   889  // test create index with not exist index name
   890  func TestCreateIndexNotExistCollName(t *testing.T) {
   891  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   892  	// connect
   893  	mc := createMilvusClient(ctx, t)
   894  
   895  	// create index
   896  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
   897  	err := mc.CreateIndex(ctx, "haha", common.DefaultFloatVecFieldName, idx, false)
   898  	common.CheckErr(t, err, false, "collection haha does not exist")
   899  }
   900  
   901  func TestCreateIndexNotExistField(t *testing.T) {
   902  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   903  	// connect
   904  	mc := createMilvusClient(ctx, t)
   905  
   906  	// create default collection with flush data
   907  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
   908  
   909  	// create index
   910  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
   911  	err := mc.CreateIndex(ctx, collName, "exist", idx, false)
   912  	common.CheckErr(t, err, false, "does not exist")
   913  }
   914  
   915  // test create index on non-vector field
   916  func TestCreateIndexNotSupportedField(t *testing.T) {
   917  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   918  	// connect
   919  	mc := createMilvusClient(ctx, t)
   920  
   921  	// create default collection with flush data
   922  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
   923  
   924  	// create index
   925  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
   926  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatFieldName, idx, false)
   927  	common.CheckErr(t, err, false, "HNSW only support float vector data type")
   928  
   929  	// create scann index
   930  	indexScann, _ := entity.NewIndexSCANN(entity.L2, 8, true)
   931  	err = mc.CreateIndex(ctx, collName, common.DefaultFloatFieldName, indexScann, false)
   932  	common.CheckErr(t, err, false, "data type should be FloatVector, Float16Vector or BFloat16Vector")
   933  }
   934  
   935  // test create index with invalid params
   936  func TestCreateIndexInvalidParams(t *testing.T) {
   937  	ctx := createContext(t, time.Second*common.DefaultTimeout)
   938  	// connect
   939  	mc := createMilvusClient(ctx, t)
   940  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
   941  
   942  	// invalid IvfFlat nlist [1, 65536]
   943  	_, errIvfFlatNlist := entity.NewIndexIvfFlat(entity.L2, 0)
   944  	_, errIvfFlatNlist2 := entity.NewIndexIvfFlat(entity.L2, 65537)
   945  	common.CheckErr(t, errIvfFlatNlist, false, "nlist has to be in range [1, 65536]")
   946  	common.CheckErr(t, errIvfFlatNlist2, false, "nlist has to be in range [1, 65536]")
   947  
   948  	// invalid IvfSq8 nlist [1, 65536]
   949  	_, errIvfSq8Nlist := entity.NewIndexIvfFlat(entity.L2, 0)
   950  	_, errIvfSq8Nlist2 := entity.NewIndexIvfFlat(entity.L2, 65537)
   951  	common.CheckErr(t, errIvfSq8Nlist, false, "nlist has to be in range [1, 65536]")
   952  	common.CheckErr(t, errIvfSq8Nlist2, false, "nlist has to be in range [1, 65536]")
   953  
   954  	// invalid IvfPq nlist [1, 65536]
   955  	_, errIvfPqNlist := entity.NewIndexIvfPQ(entity.L2, -1, 16, 8)
   956  	common.CheckErr(t, errIvfPqNlist, false, "nlist has to be in range [1, 65536]")
   957  	_, errIvfPqNlist2 := entity.NewIndexIvfPQ(entity.L2, 65538, 16, 8)
   958  	common.CheckErr(t, errIvfPqNlist2, false, "nlist has to be in range [1, 65536]")
   959  
   960  	// invalid IvfPq params m dim ≡ 0 (mod m), nbits [1, 16]
   961  	_, errIvfPqNbits := entity.NewIndexIvfPQ(entity.L2, 128, 8, 0)
   962  	common.CheckErr(t, errIvfPqNbits, false, "nbits has to be in range [1, 16]")
   963  	_, errIvfPqNbits2 := entity.NewIndexIvfPQ(entity.L2, 128, 8, 17)
   964  	common.CheckErr(t, errIvfPqNbits2, false, "nbits has to be in range [1, 16]")
   965  	// TODO unclear error message
   966  	idxInvalidm, _ := entity.NewIndexIvfPQ(entity.L2, 128, 7, 8)
   967  	errm := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idxInvalidm, false)
   968  	// TODO change error message check
   969  	common.CheckErr(t, errm, false, "dimension")
   970  
   971  	// invalid Hnsw M [4, 64], efConstruction [8, 512]
   972  	_, errHnswM := entity.NewIndexHNSW(entity.L2, 3, 96)
   973  	common.CheckErr(t, errHnswM, false, "M has to be in range [4, 64]")
   974  	_, errHnswM2 := entity.NewIndexHNSW(entity.L2, 128, 96)
   975  	common.CheckErr(t, errHnswM2, false, "M has to be in range [4, 64]")
   976  	_, errHnswEf := entity.NewIndexHNSW(entity.L2, 8, 7)
   977  	common.CheckErr(t, errHnswEf, false, "efConstruction has to be in range [8, 512]")
   978  	_, errHnswEf2 := entity.NewIndexHNSW(entity.L2, 8, 515)
   979  	common.CheckErr(t, errHnswEf2, false, "efConstruction has to be in range [8, 512]")
   980  
   981  	// invalid Scann nlist [1, 65536], with_raw_data [true, false], no default
   982  	for _, nlist := range []int{0, 65536 + 1} {
   983  		_, errScann := entity.NewIndexSCANN(entity.L2, nlist, true)
   984  		log.Println(errScann)
   985  		common.CheckErr(t, errScann, false, "nlist has to be in range [1, 65536]")
   986  	}
   987  	for _, mt := range []entity.MetricType{entity.HAMMING, entity.JACCARD, entity.SUBSTRUCTURE, entity.SUPERSTRUCTURE} {
   988  		idxScann, errScann2 := entity.NewIndexSCANN(mt, 64, true)
   989  		common.CheckErr(t, errScann2, true)
   990  		err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idxScann, false)
   991  		common.CheckErr(t, err, false,
   992  			fmt.Sprintf("metric type %s not found or not supported, supported: [L2 IP COSINE]", mt))
   993  	}
   994  
   995  	// invalid flat metric type jaccard for flat index
   996  	idx, _ := entity.NewIndexFlat(entity.JACCARD)
   997  	errMetricType := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false)
   998  	common.CheckErr(t, errMetricType, false,
   999  		"metric type JACCARD not found or not supported, supported: [L2 IP COSINE]")
  1000  }
  1001  
  1002  // test create index with nil index
  1003  func TestCreateIndexNil(t *testing.T) {
  1004  	t.Skip("Issue: https://github.com/milvus-io/milvus-sdk-go/issues/358")
  1005  	ctx := createContext(t, time.Second*common.DefaultTimeout)
  1006  	// connect
  1007  	mc := createMilvusClient(ctx, t)
  1008  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
  1009  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, nil, false)
  1010  	common.CheckErr(t, err, false, "invalid index")
  1011  }
  1012  
  1013  // test create index async true
  1014  func TestCreateIndexAsync(t *testing.T) {
  1015  	ctx := createContext(t, time.Second*common.DefaultTimeout)
  1016  	// connect
  1017  	mc := createMilvusClient(ctx, t)
  1018  
  1019  	// create default collection with flush data
  1020  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
  1021  
  1022  	// create index
  1023  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
  1024  	mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, true)
  1025  
  1026  	for {
  1027  		time.Sleep(time.Second * 10)
  1028  		indexState, errState := mc.GetIndexState(ctx, collName, common.DefaultFloatVecFieldName)
  1029  		if errState == nil {
  1030  			if indexState == 3 {
  1031  				break
  1032  			}
  1033  		} else {
  1034  			t.FailNow()
  1035  		}
  1036  	}
  1037  }
  1038  
  1039  // create same index name on different vector field
  1040  func TestIndexMultiVectorDupName(t *testing.T) {
  1041  	ctx := createContext(t, time.Second*common.DefaultTimeout)
  1042  	mc := createMilvusClient(ctx, t)
  1043  
  1044  	// create collection with all datatype
  1045  	cp := CollectionParams{CollectionFieldsType: AllVectors, AutoID: false, EnableDynamicField: true,
  1046  		ShardsNum: common.DefaultShards, Dim: common.DefaultDim}
  1047  	collName := createCollection(ctx, t, mc, cp, client.WithConsistencyLevel(entity.ClStrong))
  1048  
  1049  	// insert
  1050  	dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllVectors,
  1051  		start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false}
  1052  	_, err := insertData(ctx, t, mc, dp)
  1053  	common.CheckErr(t, err, true)
  1054  
  1055  	// create index with same indexName on different fields
  1056  	idx, _ := entity.NewIndexHNSW(entity.COSINE, 8, 96)
  1057  	err = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false, client.WithIndexName("index_1"))
  1058  	common.CheckErr(t, err, true)
  1059  
  1060  	// same index on another field
  1061  	err = mc.CreateIndex(ctx, collName, common.DefaultFloat16VecFieldName, idx, false, client.WithIndexName("index_1"))
  1062  	common.CheckErr(t, err, false, "reateIndex failed: at most one distinct index is allowed per field")
  1063  }
  1064  
  1065  // test get index state
  1066  func TestIndexState(t *testing.T) {
  1067  	ctx := createContext(t, time.Second*common.DefaultTimeout)
  1068  	// connect
  1069  	mc := createMilvusClient(ctx, t)
  1070  
  1071  	// create default collection with flush data
  1072  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
  1073  
  1074  	// create index
  1075  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
  1076  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false)
  1077  	common.CheckErr(t, err, true)
  1078  
  1079  	// get index state
  1080  	state, errState := mc.GetIndexState(ctx, collName, common.DefaultFloatVecFieldName)
  1081  	common.CheckErr(t, errState, true)
  1082  	require.Equal(t, entity.IndexState(common.IndexStateValue["Finished"]), state, "Expected finished index state")
  1083  }
  1084  
  1085  func TestIndexStateNotExistCollection(t *testing.T) {
  1086  	ctx := createContext(t, time.Second*common.DefaultTimeout)
  1087  	// connect
  1088  	mc := createMilvusClient(ctx, t)
  1089  
  1090  	// create default collection with flush data
  1091  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
  1092  
  1093  	// create index
  1094  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
  1095  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false)
  1096  	common.CheckErr(t, err, true)
  1097  
  1098  	// get index state
  1099  	_, errState := mc.GetIndexState(ctx, "collName", common.DefaultFloatVecFieldName)
  1100  	common.CheckErr(t, errState, false, "does not exist")
  1101  }
  1102  
  1103  func TestDropIndex(t *testing.T) {
  1104  	ctx := createContext(t, time.Second*common.DefaultTimeout)
  1105  	// connect
  1106  	mc := createMilvusClient(ctx, t)
  1107  
  1108  	// create default collection with flush data
  1109  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
  1110  
  1111  	// create index
  1112  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
  1113  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false)
  1114  	common.CheckErr(t, err, true)
  1115  
  1116  	// drop index
  1117  	errDrop := mc.DropIndex(ctx, collName, common.DefaultFloatVecFieldName)
  1118  	common.CheckErr(t, errDrop, true)
  1119  	indexes, errDescribe := mc.DescribeIndex(ctx, collName, common.DefaultFloatVecFieldName)
  1120  	common.CheckErr(t, errDescribe, false, "index not found")
  1121  	require.Nil(t, indexes)
  1122  }
  1123  
  1124  func TestDropIndexCreateIndex(t *testing.T) {
  1125  	//t.Skip("Issue: https://github.com/milvus-io/milvus-sdk-go/issues/385")
  1126  	ctx := createContext(t, time.Second*common.DefaultTimeout)
  1127  	// connect
  1128  	mc := createMilvusClient(ctx, t)
  1129  
  1130  	// create default collection with flush data
  1131  	collName, _ := createCollectionWithDataIndex(ctx, t, mc, false, false)
  1132  
  1133  	// create index
  1134  	idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96)
  1135  	err := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false)
  1136  	common.CheckErr(t, err, true)
  1137  
  1138  	// describe collection
  1139  	collection, _ := mc.DescribeCollection(ctx, collName)
  1140  	for _, field := range collection.Schema.Fields {
  1141  		log.Printf("field name: %v, field TypeParams: %v, field IndexParams: %v)", field.Name, field.TypeParams, field.IndexParams)
  1142  	}
  1143  
  1144  	// drop index
  1145  	errDrop := mc.DropIndex(ctx, collName, common.DefaultFloatVecFieldName)
  1146  	common.CheckErr(t, errDrop, true)
  1147  	indexes, errDescribe := mc.DescribeIndex(ctx, collName, common.DefaultFloatVecFieldName)
  1148  	common.CheckErr(t, errDescribe, false, "index not found")
  1149  	require.Nil(t, indexes)
  1150  
  1151  	// create IP index
  1152  	ipIdx, _ := entity.NewIndexHNSW(entity.IP, 8, 96)
  1153  	err2 := mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, ipIdx, false)
  1154  	common.CheckErr(t, err2, true)
  1155  
  1156  	// describe index
  1157  	ipIndexes, _ := mc.DescribeIndex(ctx, collName, common.DefaultFloatVecFieldName)
  1158  	log.Println(ipIndexes[0].Params())
  1159  
  1160  	// describe collection
  1161  	collection2, _ := mc.DescribeCollection(ctx, collName)
  1162  	for _, field := range collection2.Schema.Fields {
  1163  		log.Printf("field name: %v, field TypeParams: %v, field IndexParams: %v)", field.Name, field.TypeParams, field.IndexParams)
  1164  	}
  1165  }