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 }