github.com/milvus-io/milvus-sdk-go/v2@v2.4.1/test/testcases/query_test.go (about) 1 //go:build L0 2 3 package testcases 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "io" 9 "log" 10 "strconv" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/require" 15 16 "github.com/milvus-io/milvus-sdk-go/v2/client" 17 18 "github.com/milvus-io/milvus-sdk-go/v2/entity" 19 "github.com/milvus-io/milvus-sdk-go/v2/test/common" 20 ) 21 22 // test query from default partition 23 func TestQueryDefaultPartition(t *testing.T) { 24 ctx := createContext(t, time.Second*common.DefaultTimeout) 25 // connect 26 mc := createMilvusClient(ctx, t) 27 28 // create, insert, index 29 collName, ids := createCollectionWithDataIndex(ctx, t, mc, true, true) 30 31 // Load collection 32 errLoad := mc.LoadCollection(ctx, collName, false) 33 common.CheckErr(t, errLoad, true) 34 35 //query 36 pks := ids.Slice(0, 10) 37 var queryResult, _ = mc.QueryByPks( 38 ctx, 39 collName, 40 []string{common.DefaultPartition}, 41 pks, 42 []string{common.DefaultIntFieldName}, 43 ) 44 common.CheckQueryResult(t, queryResult, []entity.Column{pks}) 45 } 46 47 // test query with varchar field filter 48 func TestQueryVarcharField(t *testing.T) { 49 ctx := createContext(t, time.Second*common.DefaultTimeout) 50 // connect 51 mc := createMilvusClient(ctx, t) 52 53 // create, insert, index 54 collName, ids := createVarcharCollectionWithDataIndex(ctx, t, mc, true) 55 56 // Load collection 57 errLoad := mc.LoadCollection(ctx, collName, false) 58 common.CheckErr(t, errLoad, true) 59 60 //query 61 pks := ids.Slice(0, 10) 62 queryResult, _ := mc.QueryByPks( 63 ctx, 64 collName, 65 []string{common.DefaultPartition}, 66 pks, 67 []string{common.DefaultVarcharFieldName}, 68 ) 69 common.CheckQueryResult(t, queryResult, []entity.Column{pks}) 70 } 71 72 // query from not existed collection 73 func TestQueryNotExistCollection(t *testing.T) { 74 ctx := createContext(t, time.Second*common.DefaultTimeout) 75 // connect 76 mc := createMilvusClient(ctx, t) 77 78 // create, insert, index 79 collName, ids := createCollectionWithDataIndex(ctx, t, mc, true, true) 80 81 // Load collection 82 errLoad := mc.LoadCollection(ctx, collName, false) 83 common.CheckErr(t, errLoad, true) 84 85 //query 86 pks := ids.Slice(0, 10) 87 _, errQuery := mc.QueryByPks( 88 ctx, 89 "collName", 90 []string{common.DefaultPartition}, 91 pks, 92 []string{common.DefaultIntFieldName}, 93 ) 94 common.CheckErr(t, errQuery, false, "can't find collection") 95 } 96 97 // query from not existed partition 98 func TestQueryNotExistPartition(t *testing.T) { 99 ctx := createContext(t, time.Second*common.DefaultTimeout) 100 // connect 101 mc := createMilvusClient(ctx, t) 102 103 // create, insert, index 104 collName, ids := createCollectionWithDataIndex(ctx, t, mc, true, true) 105 106 // Load collection 107 errLoad := mc.LoadCollection(ctx, collName, false) 108 common.CheckErr(t, errLoad, true) 109 110 //query 111 pks := ids.Slice(0, 10) 112 _, errQuery := mc.QueryByPks( 113 ctx, 114 collName, 115 []string{"aaa"}, 116 pks, 117 []string{common.DefaultIntFieldName}, 118 ) 119 common.CheckErr(t, errQuery, false, "partition name aaa not found") 120 } 121 122 // test query with empty partition name 123 func TestQueryEmptyPartitionName(t *testing.T) { 124 emptyPartitionName := "" 125 126 ctx := createContext(t, time.Second*common.DefaultTimeout) 127 // connect 128 mc := createMilvusClient(ctx, t) 129 130 // create 131 collName := createDefaultCollection(ctx, t, mc, false, common.DefaultShards) 132 133 // insert "" partition and flush 134 intColumn, floatColumn, vecColumn := common.GenDefaultColumnData(0, common.DefaultNb, common.DefaultDim) 135 _, errInsert := mc.Insert(ctx, collName, emptyPartitionName, intColumn, floatColumn, vecColumn) 136 common.CheckErr(t, errInsert, true) 137 mc.Flush(ctx, collName, false) 138 139 // create index 140 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 141 mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false, client.WithIndexName("")) 142 143 // Load collection 144 errLoad := mc.LoadCollection(ctx, collName, false) 145 common.CheckErr(t, errLoad, true) 146 147 //query from "" partitions, expect to query from default partition 148 _, errQuery := mc.QueryByPks( 149 ctx, 150 collName, 151 []string{emptyPartitionName}, 152 intColumn.Slice(0, 10), 153 []string{common.DefaultIntFieldName}, 154 ) 155 common.CheckErr(t, errQuery, false, "Partition name should not be empty") 156 } 157 158 // query with empty partition names, actually query from all partitions 159 func TestQueryMultiPartitions(t *testing.T) { 160 ctx := createContext(t, time.Second*common.DefaultTimeout) 161 // connect 162 mc := createMilvusClient(ctx, t) 163 164 // create collection and insert [0, nb) into default partition, [nb, nb*2) into new partition 165 collName := createDefaultCollection(ctx, t, mc, false, common.DefaultShards) 166 partitionName, _, _ := createInsertTwoPartitions(ctx, t, mc, collName, common.DefaultNb) 167 168 // create index 169 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 170 mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 171 172 // Load collection 173 errLoad := mc.LoadCollection(ctx, collName, false) 174 common.CheckErr(t, errLoad, true) 175 176 //query from multi partition names 177 queryIds := entity.NewColumnInt64(common.DefaultIntFieldName, []int64{0, common.DefaultNb, common.DefaultNb*2 - 1}) 178 queryResultMultiPartition, _ := mc.QueryByPks(ctx, collName, []string{common.DefaultPartition, partitionName}, queryIds, 179 []string{common.DefaultIntFieldName}) 180 common.CheckQueryResult(t, queryResultMultiPartition, []entity.Column{queryIds}) 181 182 //query from empty partition names, expect to query from all partitions 183 queryResultEmptyPartition, _ := mc.QueryByPks(ctx, collName, []string{}, queryIds, []string{common.DefaultIntFieldName}) 184 common.CheckQueryResult(t, queryResultEmptyPartition, []entity.Column{queryIds}) 185 186 // query from new partition and query successfully 187 queryResultPartition, _ := mc.QueryByPks(ctx, collName, []string{partitionName}, queryIds, []string{common.DefaultIntFieldName}) 188 common.CheckQueryResult(t, queryResultPartition, 189 []entity.Column{entity.NewColumnInt64(common.DefaultIntFieldName, []int64{common.DefaultNb, common.DefaultNb*2 - 1})}) 190 191 // query from new partition and query gets empty pk column data 192 queryResultEmpty, errQuery := mc.QueryByPks(ctx, collName, []string{partitionName}, entity.NewColumnInt64(common.DefaultIntFieldName, 193 []int64{0}), []string{common.DefaultIntFieldName}) 194 common.CheckErr(t, errQuery, true) 195 require.Equalf(t, queryResultEmpty[0].Len(), 0, 196 fmt.Sprintf("Expected query return empty pk column data, but gets data: %d", queryResultEmpty[0].(*entity.ColumnInt64).Data())) 197 } 198 199 // test query with empty ids 200 // TODO Issue: https://github.com/milvus-io/milvus-sdk-go/issues/365 201 func TestQueryEmptyIds(t *testing.T) { 202 ctx := createContext(t, time.Second*common.DefaultTimeout) 203 // connect 204 mc := createMilvusClient(ctx, t) 205 206 // create, insert, index 207 collName, _ := createCollectionWithDataIndex(ctx, t, mc, true, true) 208 209 // Load collection 210 errLoad := mc.LoadCollection(ctx, collName, false) 211 common.CheckErr(t, errLoad, true) 212 213 //query 214 queryIds := entity.NewColumnInt64(common.DefaultIntFieldName, []int64{}) 215 _, errQuery := mc.QueryByPks( 216 ctx, 217 collName, 218 []string{common.DefaultPartition}, 219 queryIds, 220 []string{common.DefaultIntFieldName}, 221 ) 222 common.CheckErr(t, errQuery, false, "ids len must not be zero") 223 } 224 225 // test query with non-primary field filter, and output scalar fields 226 func TestQueryNonPrimaryFields(t *testing.T) { 227 t.Parallel() 228 ctx := createContext(t, time.Second*common.DefaultTimeout) 229 // connect 230 mc := createMilvusClient(ctx, t) 231 232 // create and insert 233 collName, _ := createCollectionAllFields(ctx, t, mc, common.DefaultNb, 0) 234 mc.Flush(ctx, collName, false) 235 236 // create index 237 indexHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 238 indexBinary, _ := entity.NewIndexBinIvfFlat(entity.JACCARD, 64) 239 for _, fieldName := range common.AllVectorsFieldsName { 240 if fieldName == common.DefaultBinaryVecFieldName { 241 mc.CreateIndex(ctx, collName, fieldName, indexBinary, false) 242 } else { 243 mc.CreateIndex(ctx, collName, fieldName, indexHnsw, false) 244 } 245 } 246 247 // Load collection 248 errLoad := mc.LoadCollection(ctx, collName, false) 249 common.CheckErr(t, errLoad, true) 250 251 // query with non-primary field 252 queryIds := []entity.Column{ 253 entity.NewColumnBool("bool", []bool{true}), 254 entity.NewColumnInt8("int8", []int8{0}), 255 entity.NewColumnInt16("int16", []int16{0}), 256 entity.NewColumnInt32("int32", []int32{0}), 257 entity.NewColumnFloat("float", []float32{0}), 258 entity.NewColumnDouble("double", []float64{0}), 259 } 260 261 for _, idsColumn := range queryIds { 262 _, errQuery := mc.QueryByPks(ctx, collName, []string{common.DefaultPartition}, idsColumn, 263 []string{common.DefaultIntFieldName}) 264 265 // TODO only int64 and varchar column can be primary key for now 266 common.CheckErr(t, errQuery, false, "only int64 and varchar column can be primary key for now") 267 //common.CheckQueryResult(t, queryResultMultiPartition, []entity.Column{entity.NewColumnInt64(common.DefaultIntFieldName, []int64{0})}) 268 } 269 } 270 271 // test query empty or one scalar output fields 272 func TestQueryEmptyOutputFields(t *testing.T) { 273 t.Parallel() 274 ctx := createContext(t, time.Second*common.DefaultTimeout) 275 // connect 276 mc := createMilvusClient(ctx, t) 277 for _, enableDynamic := range []bool{true, false} { 278 // create, insert, index 279 collName, ids := createCollectionWithDataIndex(ctx, t, mc, true, true, client.WithEnableDynamicSchema(enableDynamic)) 280 281 // Load collection 282 errLoad := mc.LoadCollection(ctx, collName, false) 283 common.CheckErr(t, errLoad, true) 284 285 //query with empty output fields []string{}-> output "int64" 286 queryEmptyOutputs, _ := mc.QueryByPks( 287 ctx, collName, []string{common.DefaultPartition}, 288 ids.Slice(0, 10), 289 []string{}, 290 ) 291 common.CheckOutputFields(t, queryEmptyOutputs, []string{common.DefaultIntFieldName}) 292 293 //query with empty output fields []string{""}-> output "int64" and dynamic field 294 queryEmptyOutputs, err := mc.QueryByPks( 295 ctx, collName, []string{common.DefaultPartition}, 296 ids.Slice(0, 10), 297 []string{""}, 298 ) 299 if enableDynamic { 300 common.CheckErr(t, err, false, "parse output field name failed") 301 } else { 302 common.CheckErr(t, err, false, "not exist") 303 } 304 305 // query with "float" output fields -> output "int64, float" 306 queryFloatOutputs, _ := mc.QueryByPks( 307 ctx, collName, []string{common.DefaultPartition}, 308 ids.Slice(0, 10), 309 []string{common.DefaultFloatFieldName}, 310 ) 311 common.CheckOutputFields(t, queryFloatOutputs, []string{common.DefaultIntFieldName, common.DefaultFloatFieldName}) 312 } 313 } 314 315 // test query output int64 and float and floatVector fields 316 func TestQueryOutputFields(t *testing.T) { 317 ctx := createContext(t, time.Second*common.DefaultTimeout) 318 // connect 319 mc := createMilvusClient(ctx, t) 320 321 // create collection and insert data into default partition, pks from 0 to DefaultNb 322 collName := createDefaultCollection(ctx, t, mc, false, common.DefaultShards) 323 intColumn, floatColumn, vecColumn := common.GenDefaultColumnData(common.DefaultNb, common.DefaultNb, common.DefaultDim) 324 _, errInsert := mc.Insert(ctx, collName, "", intColumn, floatColumn, vecColumn) 325 common.CheckErr(t, errInsert, true) 326 mc.Flush(ctx, collName, false) 327 stats, _ := mc.GetCollectionStatistics(ctx, collName) 328 require.Equal(t, strconv.Itoa(common.DefaultNb), stats[common.RowCount]) 329 330 // create index 331 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 332 mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 333 334 // Load collection 335 errLoad := mc.LoadCollection(ctx, collName, false) 336 common.CheckErr(t, errLoad, true) 337 338 //query 339 pos := 10 340 queryResult, _ := mc.QueryByPks( 341 ctx, collName, 342 []string{common.DefaultPartition}, 343 intColumn.Slice(0, pos), 344 []string{common.DefaultIntFieldName, common.DefaultFloatFieldName, common.DefaultFloatVecFieldName}, 345 ) 346 common.CheckQueryResult(t, queryResult, []entity.Column{ 347 intColumn.Slice(0, pos), 348 floatColumn.Slice(0, pos), 349 vecColumn.Slice(0, pos)}) 350 common.CheckOutputFields(t, queryResult, []string{common.DefaultIntFieldName, common.DefaultFloatFieldName, common.DefaultFloatVecFieldName}) 351 } 352 353 // test query output varchar and binaryVector fields 354 func TestQueryOutputBinaryAndVarchar(t *testing.T) { 355 ctx := createContext(t, time.Second*common.DefaultTimeout) 356 // connect 357 mc := createMilvusClient(ctx, t) 358 359 // create collection and insert data into default partition, pks from 0 to DefaultNb 360 collName := createDefaultVarcharCollection(ctx, t, mc) 361 varcharColumn, vecColumn := common.GenDefaultVarcharData(0, common.DefaultNb, common.DefaultDim) 362 _, errInsert := mc.Insert(ctx, collName, "", varcharColumn, vecColumn) 363 common.CheckErr(t, errInsert, true) 364 mc.Flush(ctx, collName, false) 365 stats, _ := mc.GetCollectionStatistics(ctx, collName) 366 require.Equal(t, strconv.Itoa(common.DefaultNb), stats[common.RowCount]) 367 368 // create index 369 idx, _ := entity.NewIndexBinIvfFlat(entity.JACCARD, 128) 370 err := mc.CreateIndex(ctx, collName, common.DefaultBinaryVecFieldName, idx, false, client.WithIndexName("")) 371 common.CheckErr(t, err, true) 372 373 // Load collection 374 errLoad := mc.LoadCollection(ctx, collName, false) 375 common.CheckErr(t, errLoad, true) 376 377 //query 378 pos := 10 379 queryResult, _ := mc.QueryByPks( 380 ctx, 381 collName, 382 []string{common.DefaultPartition}, 383 varcharColumn.Slice(0, pos), 384 []string{common.DefaultBinaryVecFieldName}, 385 ) 386 common.CheckQueryResult(t, queryResult, []entity.Column{ 387 varcharColumn.Slice(0, pos), 388 vecColumn.Slice(0, pos)}) 389 common.CheckOutputFields(t, queryResult, []string{common.DefaultBinaryVecFieldName, common.DefaultVarcharFieldName}) 390 } 391 392 // test query output all fields 393 func TestOutputAllFieldsRows(t *testing.T) { 394 ctx := createContext(t, time.Second*common.DefaultTimeout) 395 // connect 396 mc := createMilvusClient(ctx, t) 397 398 // create collection 399 var capacity int64 = common.TestCapacity 400 cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true, 401 ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxCapacity: capacity} 402 collName := createCollection(ctx, t, mc, cp) 403 404 // prepare and insert data 405 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields, 406 start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: true} 407 _, _ = insertData(ctx, t, mc, dp, common.WithArrayCapacity(capacity)) 408 409 // flush and check row count 410 errFlush := mc.Flush(ctx, collName, false) 411 common.CheckErr(t, errFlush, true) 412 413 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 414 for _, fieldName := range []string{"floatVec", "fp16Vec", "bf16Vec"} { 415 _ = mc.CreateIndex(ctx, collName, fieldName, idx, false) 416 } 417 binIdx, _ := entity.NewIndexBinFlat(entity.JACCARD, 16) 418 _ = mc.CreateIndex(ctx, collName, "binaryVec", binIdx, false) 419 420 // Load collection 421 errLoad := mc.LoadCollection(ctx, collName, false) 422 common.CheckErr(t, errLoad, true) 423 424 // query output all fields -> output all fields, includes vector and $meta field 425 allFieldsName := append(common.AllArrayFieldsName, "int64", "bool", "int8", "int16", "int32", "float", 426 "double", "varchar", "json", "floatVec", "fp16Vec", "bf16Vec", "binaryVec", common.DefaultDynamicFieldName) 427 queryResultAll, errQuery := mc.Query(ctx, collName, []string{}, 428 fmt.Sprintf("%s == 0", common.DefaultIntFieldName), []string{"*"}) 429 common.CheckErr(t, errQuery, true) 430 common.CheckOutputFields(t, queryResultAll, allFieldsName) 431 } 432 433 // test query output all fields and verify data 434 func TestOutputAllFieldsColumn(t *testing.T) { 435 ctx := createContext(t, time.Second*common.DefaultTimeout) 436 // connect 437 mc := createMilvusClient(ctx, t) 438 439 // create collection 440 var capacity int64 = common.TestCapacity 441 for _, isDynamic := range [2]bool{true, false} { 442 cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: isDynamic, 443 ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxCapacity: capacity} 444 collName := createCollection(ctx, t, mc, cp) 445 446 // prepare and insert data 447 data := common.GenAllFieldsData(0, common.DefaultNb, common.DefaultDim, common.WithArrayCapacity(10)) 448 _data := data 449 if isDynamic { 450 _data = append(_data, common.GenDynamicFieldData(0, common.DefaultNb)...) 451 } 452 ids, err := mc.Insert(ctx, collName, "", _data...) 453 common.CheckErr(t, err, true) 454 require.Equal(t, common.DefaultNb, ids.Len()) 455 456 // flush and check row count 457 errFlush := mc.Flush(ctx, collName, false) 458 common.CheckErr(t, errFlush, true) 459 460 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 461 for _, fieldName := range []string{"floatVec", "fp16Vec", "bf16Vec"} { 462 _ = mc.CreateIndex(ctx, collName, fieldName, idx, false) 463 } 464 binIdx, _ := entity.NewIndexBinFlat(entity.JACCARD, 16) 465 _ = mc.CreateIndex(ctx, collName, "binaryVec", binIdx, false) 466 467 // Load collection 468 errLoad := mc.LoadCollection(ctx, collName, false) 469 common.CheckErr(t, errLoad, true) 470 471 // query output all fields -> output all fields, includes vector and $meta field 472 pos := 10 473 allFieldsName := append(common.AllArrayFieldsName, "int64", "bool", "int8", "int16", "int32", "float", 474 "double", "varchar", "json", "floatVec", "fp16Vec", "bf16Vec", "binaryVec") 475 if isDynamic { 476 allFieldsName = append(allFieldsName, common.DefaultDynamicFieldName) 477 } 478 queryResultAll, errQuery := mc.Query(ctx, collName, []string{}, fmt.Sprintf("%s < %d", common.DefaultIntFieldName, pos), []string{"*"}) 479 common.CheckErr(t, errQuery, true) 480 common.CheckOutputFields(t, queryResultAll, allFieldsName) 481 482 expColumns := make([]entity.Column, 0, len(data)+1) 483 for _, column := range data { 484 expColumns = append(expColumns, column.Slice(0, pos)) 485 } 486 if isDynamic { 487 expColumns = append(expColumns, common.MergeColumnsToDynamic(pos, common.GenDynamicFieldData(0, pos))) 488 } 489 common.CheckQueryResult(t, queryResultAll, expColumns) 490 } 491 } 492 493 // test query with an not existed field 494 func TestQueryOutputNotExistField(t *testing.T) { 495 ctx := createContext(t, time.Second*common.DefaultTimeout) 496 // connect 497 mc := createMilvusClient(ctx, t) 498 499 // create, insert, index 500 collName, ids := createCollectionWithDataIndex(ctx, t, mc, true, true) 501 502 // Load collection 503 errLoad := mc.LoadCollection(ctx, collName, false) 504 common.CheckErr(t, errLoad, true) 505 506 //query 507 _, errQuery := mc.QueryByPks( 508 ctx, 509 collName, 510 []string{common.DefaultPartition}, 511 ids.Slice(0, 10), 512 []string{common.DefaultIntFieldName, "varchar"}, 513 ) 514 common.CheckErr(t, errQuery, false, "field varchar not exist") 515 } 516 517 // Test query json collection, filter json field, output json field 518 func TestQueryJsonDynamicField(t *testing.T) { 519 t.Parallel() 520 ctx := createContext(t, time.Second*common.DefaultTimeout) 521 // connect 522 mc := createMilvusClient(ctx, t) 523 524 for _, dynamicField := range []bool{true, false} { 525 // create collection 526 cp := CollectionParams{CollectionFieldsType: Int64FloatVecJSON, AutoID: false, EnableDynamicField: dynamicField, 527 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 528 collName := createCollection(ctx, t, mc, cp) 529 530 // insert 531 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVecJSON, 532 start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: dynamicField} 533 _, _ = insertData(ctx, t, mc, dp) 534 535 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 536 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 537 538 // Load collection 539 errLoad := mc.LoadCollection(ctx, collName, false) 540 common.CheckErr(t, errLoad, true) 541 542 outputFields := []string{common.DefaultIntFieldName, common.DefaultJSONFieldName} 543 if dynamicField { 544 outputFields = append(outputFields, common.DefaultDynamicFieldName) 545 } 546 547 // query and output json/dynamic field 548 pkColumn := entity.NewColumnInt64(common.DefaultIntFieldName, []int64{0, 1}) 549 queryResult, err := mc.QueryByPks( 550 ctx, collName, 551 []string{common.DefaultPartition}, 552 pkColumn, 553 outputFields, 554 ) 555 common.CheckErr(t, err, true) 556 m0 := common.JSONStruct{String: strconv.Itoa(0), Bool: true} 557 j0, _ := json.Marshal(&m0) 558 m1 := common.JSONStruct{Number: int32(1), String: strconv.Itoa(1), Bool: false, List: []int64{int64(1), int64(2)}} 559 j1, _ := json.Marshal(&m1) 560 jsonValues := [][]byte{j0, j1} 561 jsonColumn := entity.NewColumnJSONBytes(common.DefaultJSONFieldName, jsonValues) 562 actualColumns := []entity.Column{pkColumn, jsonColumn} 563 if dynamicField { 564 dynamicColumn := common.MergeColumnsToDynamic(2, common.GenDynamicFieldData(0, 2)) 565 actualColumns = append(actualColumns, dynamicColumn) 566 } 567 568 for _, column := range queryResult { 569 log.Println(column.FieldData()) 570 if column.Type() == entity.FieldTypeJSON { 571 var jsonData []string 572 for i := 0; i < column.Len(); i++ { 573 line, err := column.GetAsString(i) 574 if err != nil { 575 fmt.Println(err) 576 } 577 jsonData = append(jsonData, line) 578 } 579 log.Println(jsonData) 580 } 581 } 582 common.CheckQueryResult(t, queryResult, actualColumns) 583 584 // query with json column 585 queryResult, err = mc.QueryByPks( 586 ctx, collName, 587 []string{common.DefaultPartition}, 588 jsonColumn, 589 []string{common.DefaultIntFieldName, common.DefaultJSONFieldName}, 590 ) 591 common.CheckErr(t, err, false, "only int64 and varchar column can be primary key for now") 592 593 // query with dynamic column 594 queryResult, err = mc.QueryByPks( 595 ctx, collName, 596 []string{common.DefaultPartition}, 597 common.MergeColumnsToDynamic(2, common.GenDynamicFieldData(0, 2)), 598 []string{common.DefaultIntFieldName, common.DefaultJSONFieldName}, 599 ) 600 common.CheckErr(t, err, false, "only int64 and varchar column can be primary key for now") 601 } 602 } 603 604 // Test query json and dynamic collection with string expr 605 func TestQueryCountJsonDynamicExpr(t *testing.T) { 606 t.Parallel() 607 ctx := createContext(t, time.Second*common.DefaultTimeout) 608 // connect 609 mc := createMilvusClient(ctx, t) 610 611 // create collection 612 cp := CollectionParams{ 613 CollectionFieldsType: Int64FloatVecJSON, 614 AutoID: false, 615 EnableDynamicField: true, 616 ShardsNum: common.DefaultShards, 617 Dim: common.DefaultDim, 618 } 619 collName := createCollection(ctx, t, mc, cp) 620 621 // insert 622 dp := DataParams{ 623 CollectionName: collName, 624 PartitionName: "", 625 CollectionFieldsType: Int64FloatVecJSON, 626 start: 0, 627 nb: common.DefaultNb, 628 dim: common.DefaultDim, 629 EnableDynamicField: true, 630 } 631 _, _ = insertData(ctx, t, mc, dp) 632 633 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 634 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 635 636 // Load collection 637 errLoad := mc.LoadCollection(ctx, collName, false) 638 common.CheckErr(t, errLoad, true) 639 640 // query with different expr and count 641 type exprCount struct { 642 expr string 643 count int64 644 } 645 exprCounts := []exprCount{ 646 {expr: "", count: common.DefaultNb}, 647 // pk int64 field expr: < in && || 648 {expr: fmt.Sprintf("%s < 1000", common.DefaultIntFieldName), count: 1000}, 649 {expr: fmt.Sprintf("%s in [0, 1, 2]", common.DefaultIntFieldName), count: 3}, 650 {expr: fmt.Sprintf("%s >= 1000 && %s < 2000", common.DefaultIntFieldName, common.DefaultIntFieldName), count: 1000}, 651 {expr: fmt.Sprintf("%s >= 1000 || %s > 2000", common.DefaultIntFieldName, common.DefaultIntFieldName), count: 2000}, 652 {expr: fmt.Sprintf("%s < 1000", common.DefaultFloatFieldName), count: 1000}, 653 654 // json and dynamic field filter expr: == < in bool/ list/ int 655 {expr: fmt.Sprintf("%s['number'] == 0", common.DefaultJSONFieldName), count: 1500 / 2}, 656 {expr: fmt.Sprintf("%s['number'] < 100 and %s['number'] != 0", common.DefaultJSONFieldName, common.DefaultJSONFieldName), count: 50}, 657 {expr: fmt.Sprintf("%s < 100", common.DefaultDynamicNumberField), count: 100}, 658 {expr: "dynamicNumber % 2 == 0", count: 1500}, 659 {expr: fmt.Sprintf("%s['bool'] == true", common.DefaultJSONFieldName), count: 1500 / 2}, 660 {expr: fmt.Sprintf("%s == false", common.DefaultDynamicBoolField), count: 2000}, 661 {expr: fmt.Sprintf("%s in ['1', '2'] ", common.DefaultDynamicStringField), count: 2}, 662 {expr: fmt.Sprintf("%s['string'] in ['1', '2', '5'] ", common.DefaultJSONFieldName), count: 3}, 663 {expr: fmt.Sprintf("%s['list'] == [1, 2] ", common.DefaultJSONFieldName), count: 1}, 664 {expr: fmt.Sprintf("%s['list'] == [0, 1] ", common.DefaultJSONFieldName), count: 0}, 665 {expr: fmt.Sprintf("%s['list'][0] < 10 ", common.DefaultJSONFieldName), count: 5}, 666 {expr: fmt.Sprintf("%s[\"dynamicList\"] != [2, 3]", common.DefaultDynamicFieldName), count: 0}, 667 668 // json contains 669 {expr: fmt.Sprintf("json_contains (%s['list'], 2)", common.DefaultJSONFieldName), count: 1}, 670 {expr: fmt.Sprintf("json_contains (%s['number'], 0)", common.DefaultJSONFieldName), count: 0}, 671 {expr: fmt.Sprintf("json_contains_all (%s['list'], [1, 2])", common.DefaultJSONFieldName), count: 1}, 672 {expr: fmt.Sprintf("JSON_CONTAINS_ANY (%s['list'], [1, 3])", common.DefaultJSONFieldName), count: 2}, 673 // string like 674 {expr: "dynamicString like '1%' ", count: 1111}, 675 676 // key exist 677 {expr: fmt.Sprintf("exists %s['list']", common.DefaultJSONFieldName), count: common.DefaultNb / 2}, 678 {expr: fmt.Sprintf("exists a "), count: 0}, 679 {expr: fmt.Sprintf("exists %s ", common.DefaultDynamicListField), count: 0}, 680 {expr: fmt.Sprintf("exists %s ", common.DefaultDynamicStringField), count: common.DefaultNb}, 681 // data type not match and no error 682 {expr: fmt.Sprintf("%s['number'] == '0' ", common.DefaultJSONFieldName), count: 0}, 683 684 // json field 685 {expr: fmt.Sprintf("%s >= 1500", common.DefaultJSONFieldName), count: 1500 / 2}, // json >= 1500 686 {expr: fmt.Sprintf("%s > 1499.5", common.DefaultJSONFieldName), count: 1500 / 2}, // json >= 1500.0 687 {expr: fmt.Sprintf("%s like '21%%'", common.DefaultJSONFieldName), count: 100 / 4}, // json like '21%' 688 {expr: fmt.Sprintf("%s == [1503, 1504]", common.DefaultJSONFieldName), count: 1}, // json == [1,2] 689 {expr: fmt.Sprintf("%s[0] > 1", common.DefaultJSONFieldName), count: 1500 / 4}, // json[0] > 1 690 {expr: fmt.Sprintf("%s[0][0] > 1", common.DefaultJSONFieldName), count: 0}, // json == [1,2] 691 } 692 693 for _, _exprCount := range exprCounts { 694 countRes, _ := mc.Query(ctx, collName, 695 []string{common.DefaultPartition}, 696 _exprCount.expr, []string{common.QueryCountFieldName}) 697 require.Equal(t, _exprCount.count, countRes.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 698 } 699 } 700 701 // test query with all kinds of array expr 702 func TestQueryArrayFieldExpr(t *testing.T) { 703 ctx := createContext(t, time.Second*common.DefaultTimeout) 704 // connect 705 mc := createMilvusClient(ctx, t) 706 707 for _, withRows := range []bool{true, false} { 708 // create collection 709 var capacity int64 = common.TestCapacity 710 cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true, 711 ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxCapacity: capacity} 712 collName := createCollection(ctx, t, mc, cp, client.WithConsistencyLevel(entity.ClStrong)) 713 714 // prepare and insert data 715 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields, 716 start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: withRows} 717 _, _ = insertData(ctx, t, mc, dp, common.WithArrayCapacity(capacity)) 718 719 // flush and check row count 720 errFlush := mc.Flush(ctx, collName, false) 721 common.CheckErr(t, errFlush, true) 722 723 // index 724 indexHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 725 indexBinary, _ := entity.NewIndexBinIvfFlat(entity.JACCARD, 64) 726 for _, fieldName := range common.AllVectorsFieldsName { 727 if fieldName == common.DefaultBinaryVecFieldName { 728 err := mc.CreateIndex(ctx, collName, fieldName, indexBinary, false) 729 common.CheckErr(t, err, true) 730 } else { 731 err := mc.CreateIndex(ctx, collName, fieldName, indexHnsw, false) 732 common.CheckErr(t, err, true) 733 } 734 } 735 736 // Load collection 737 errLoad := mc.LoadCollection(ctx, collName, false) 738 common.CheckErr(t, errLoad, true) 739 740 type exprCount struct { 741 expr string 742 count int64 743 } 744 exprCounts := []exprCount{ 745 {expr: fmt.Sprintf("%s[0] == false", common.DefaultBoolArrayField), count: common.DefaultNb / 2}, // array[0] == 746 {expr: fmt.Sprintf("%s[0] > 0", common.DefaultInt64ArrayField), count: common.DefaultNb - 1}, // array[0] > 747 {expr: fmt.Sprintf("%s[0] > 0", common.DefaultInt8ArrayField), count: 1524}, // array[0] > int8 range: [-128, 127] 748 {expr: fmt.Sprintf("json_contains (%s, %d)", common.DefaultInt16ArrayField, capacity), count: capacity}, // json_contains(array, 1) 749 {expr: fmt.Sprintf("array_contains (%s, %d)", common.DefaultInt16ArrayField, capacity), count: capacity}, // array_contains(array, 1) 750 {expr: fmt.Sprintf("array_contains (%s, 1)", common.DefaultInt32ArrayField), count: 2}, // array_contains(array, 1) 751 {expr: fmt.Sprintf("json_contains (%s, 1)", common.DefaultInt32ArrayField), count: 2}, // json_contains(array, 1) 752 {expr: fmt.Sprintf("array_contains (%s, 1000000)", common.DefaultInt32ArrayField), count: 0}, // array_contains(array, 1) 753 {expr: fmt.Sprintf("json_contains_all (%s, [90, 91])", common.DefaultInt64ArrayField), count: 91}, // json_contains_all(array, [x]) 754 {expr: fmt.Sprintf("array_contains_all (%s, [1, 2])", common.DefaultInt64ArrayField), count: 2}, // array_contains_all(array, [x]) 755 {expr: fmt.Sprintf("array_contains_any (%s, [0, 100, 10000])", common.DefaultFloatArrayField), count: 101}, // array_contains_any(array, [x]) 756 {expr: fmt.Sprintf("json_contains_any (%s, [0, 100, 10])", common.DefaultFloatArrayField), count: 101}, // json_contains_any (array, [x]) 757 {expr: fmt.Sprintf("%s == [0, 1]", common.DefaultDoubleArrayField), count: 0}, // array == 758 {expr: fmt.Sprintf("array_length(%s) == 10", common.DefaultVarcharArrayField), count: 0}, // array_length 759 {expr: fmt.Sprintf("array_length(%s) == %d", common.DefaultDoubleArrayField, capacity), count: common.DefaultNb}, // array_length 760 } 761 762 for _, _exprCount := range exprCounts { 763 log.Println(_exprCount.expr) 764 countRes, err := mc.Query(ctx, collName, 765 []string{}, _exprCount.expr, []string{common.QueryCountFieldName}) 766 log.Println(countRes.GetColumn(common.QueryCountFieldName).FieldData()) 767 common.CheckErr(t, err, true) 768 require.Equal(t, _exprCount.count, countRes.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 769 } 770 } 771 } 772 773 // test query different array rows has different element length 774 func TestQueryArrayDifferentLenBetweenRows(t *testing.T) { 775 ctx := createContext(t, time.Second*common.DefaultTimeout) 776 // connect 777 mc := createMilvusClient(ctx, t) 778 779 // fields 780 defaultFields := common.GenDefaultFields(false) 781 int64ArrayField := common.GenField(common.DefaultInt32ArrayField, entity.FieldTypeArray, 782 common.WithElementType(entity.FieldTypeInt32), common.WithMaxCapacity(common.TestCapacity)) 783 784 // create collection with max 785 collName := common.GenRandomString(4) 786 schema := common.GenSchema(collName, false, append(defaultFields, int64ArrayField), common.WithEnableDynamicField(true)) 787 err := mc.CreateCollection(ctx, schema, common.DefaultShards, client.WithConsistencyLevel(entity.ClStrong)) 788 common.CheckErr(t, err, true) 789 790 // insert data [0, 1500) with array length = capacity, values: [i+0, i+ 100) 791 intColumn, floatColumn, vecColumn := common.GenDefaultColumnData(0, common.DefaultNb/2, common.DefaultDim) 792 data := []entity.Column{ 793 intColumn, 794 floatColumn, 795 vecColumn, 796 common.GenArrayColumnData(0, common.DefaultNb/2, common.DefaultInt32ArrayField, 797 common.WithArrayElementType(entity.FieldTypeInt32), common.WithArrayCapacity(common.TestCapacity)), 798 } 799 ids, err := mc.Insert(ctx, collName, "", data...) 800 common.CheckErr(t, err, true) 801 802 // insert data [1500, 3000) with array length = capacity/2, values: values: [i+0, i+ 50) 803 require.Equal(t, common.DefaultNb/2, ids.Len()) 804 intColumn1, floatColumn1, vecColumn1 := common.GenDefaultColumnData(common.DefaultNb/2, common.DefaultNb/2, common.DefaultDim) 805 data1 := []entity.Column{ 806 intColumn1, 807 floatColumn1, 808 vecColumn1, 809 common.GenArrayColumnData(common.DefaultNb/2, common.DefaultNb/2, common.DefaultInt32ArrayField, 810 common.WithArrayElementType(entity.FieldTypeInt32), common.WithArrayCapacity(common.TestCapacity/2)), 811 } 812 ids, err = mc.Insert(ctx, collName, "", data1...) 813 common.CheckErr(t, err, true) 814 require.Equal(t, common.DefaultNb/2, ids.Len()) 815 816 // flush and check row count 817 errFlush := mc.Flush(ctx, collName, false) 818 common.CheckErr(t, errFlush, true) 819 820 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 821 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 822 823 // Load collection 824 errLoad := mc.LoadCollection(ctx, collName, false) 825 common.CheckErr(t, errLoad, true) 826 827 // query array idx exceeds max capacity, array[100] 828 countRes, err := mc.Query(ctx, collName, []string{}, fmt.Sprintf("%s[%d] > 0", common.DefaultInt32ArrayField, common.TestCapacity), 829 []string{common.QueryCountFieldName}) 830 common.CheckErr(t, err, true) 831 require.Equal(t, int64(0), countRes.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 832 833 // query: some rows has element less than expr index array[51] 834 countRes, err = mc.Query(ctx, collName, []string{}, fmt.Sprintf("%s[%d] > 0", common.DefaultInt32ArrayField, common.TestCapacity/2+1), 835 []string{common.QueryCountFieldName}) 836 common.CheckErr(t, err, true) 837 require.Equal(t, int64(common.DefaultNb/2), countRes.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 838 } 839 840 // test query with expr and verify output dynamic field data 841 func TestQueryJsonDynamicExpr(t *testing.T) { 842 t.Parallel() 843 ctx := createContext(t, time.Second*common.DefaultTimeout) 844 // connect 845 mc := createMilvusClient(ctx, t) 846 847 // create collection 848 cp := CollectionParams{ 849 CollectionFieldsType: Int64FloatVecJSON, 850 AutoID: false, 851 EnableDynamicField: true, 852 ShardsNum: common.DefaultShards, 853 Dim: common.DefaultDim, 854 } 855 collName := createCollection(ctx, t, mc, cp) 856 857 // insert 858 dp := DataParams{ 859 CollectionName: collName, 860 PartitionName: "", 861 CollectionFieldsType: Int64FloatVecJSON, 862 start: 0, 863 nb: common.DefaultNb, 864 dim: common.DefaultDim, 865 EnableDynamicField: true, 866 } 867 _, _ = insertData(ctx, t, mc, dp) 868 869 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 870 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 871 872 // Load collection 873 errLoad := mc.LoadCollection(ctx, collName, false) 874 common.CheckErr(t, errLoad, true) 875 876 // query with different expr and count 877 expr := fmt.Sprintf("%s['number'] < 10 and %s < 10", common.DefaultJSONFieldName, common.DefaultDynamicNumberField) 878 queryRes, err := mc.Query(ctx, collName, 879 []string{common.DefaultPartition}, 880 expr, []string{common.DefaultJSONFieldName, common.DefaultDynamicNumberField}) 881 882 if err != nil { 883 log.Println(err) 884 } 885 // verify output fields and count, dynamicNumber value 886 common.CheckOutputFields(t, queryRes, []string{common.DefaultIntFieldName, common.DefaultJSONFieldName, common.DefaultDynamicNumberField}) 887 require.Equal(t, 10, queryRes.GetColumn(common.DefaultJSONFieldName).Len()) 888 dynamicNumColumn := queryRes.GetColumn(common.DefaultDynamicNumberField) 889 var numberData []int64 890 for i := 0; i < dynamicNumColumn.Len(); i++ { 891 line, _ := dynamicNumColumn.GetAsInt64(i) 892 numberData = append(numberData, line) 893 } 894 require.Equal(t, numberData, []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}) 895 } 896 897 // test query and output both json and dynamic field 898 func TestQueryJsonDynamicFieldRows(t *testing.T) { 899 ctx := createContext(t, time.Second*common.DefaultTimeout) 900 // connect 901 mc := createMilvusClient(ctx, t) 902 903 // create collection 904 cp := CollectionParams{CollectionFieldsType: Int64FloatVecJSON, AutoID: false, EnableDynamicField: true, 905 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 906 collName := createCollection(ctx, t, mc, cp) 907 908 // insert 909 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVecJSON, 910 start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: true} 911 _, _ = insertData(ctx, t, mc, dp) 912 913 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 914 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 915 916 // Load collection 917 errLoad := mc.LoadCollection(ctx, collName, false) 918 common.CheckErr(t, errLoad, true) 919 920 countRes, _ := mc.Query(ctx, collName, 921 []string{common.DefaultPartition}, 922 "", []string{common.QueryCountFieldName}) 923 require.Equal(t, int64(common.DefaultNb), countRes.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 924 925 // query and output json field 926 pkColumn := entity.NewColumnInt64(common.DefaultIntFieldName, []int64{0, 1}) 927 queryResult, err := mc.QueryByPks( 928 ctx, collName, 929 []string{common.DefaultPartition}, 930 pkColumn, 931 []string{common.DefaultIntFieldName, common.DefaultJSONFieldName, common.DefaultDynamicFieldName}, 932 ) 933 common.CheckErr(t, err, true) 934 m0 := common.JSONStruct{String: strconv.Itoa(0), Bool: true} 935 j0, _ := json.Marshal(&m0) 936 m1 := common.JSONStruct{Number: int32(1), String: strconv.Itoa(1), Bool: false, List: []int64{int64(1), int64(2)}} 937 j1, _ := json.Marshal(&m1) 938 jsonValues := [][]byte{j0, j1} 939 jsonColumn := entity.NewColumnJSONBytes(common.DefaultJSONFieldName, jsonValues) 940 dynamicColumn := common.MergeColumnsToDynamic(10, common.GenDynamicFieldData(0, 10)) 941 // gen dynamic json column 942 943 for _, column := range queryResult { 944 log.Printf("name: %s, type: %s, fieldData: %v", column.Name(), column.Type(), column.FieldData()) 945 if column.Type() == entity.FieldTypeJSON { 946 var jsonData []string 947 for i := 0; i < column.Len(); i++ { 948 line, err := column.GetAsString(i) 949 if err != nil { 950 fmt.Println(err) 951 } 952 jsonData = append(jsonData, line) 953 } 954 log.Println(jsonData) 955 } 956 } 957 common.CheckQueryResult(t, queryResult, []entity.Column{pkColumn, jsonColumn, dynamicColumn.Slice(0, 2)}) 958 959 // query with different expr and count 960 expr := fmt.Sprintf("%s['number'] < 10 && %s < 10", common.DefaultJSONFieldName, common.DefaultDynamicNumberField) 961 queryRes, _ := mc.Query(ctx, collName, 962 []string{common.DefaultPartition}, expr, []string{common.DefaultDynamicNumberField}) 963 964 // verify output fields and count, dynamicNumber value 965 common.CheckOutputFields(t, queryRes, []string{common.DefaultIntFieldName, common.DefaultDynamicNumberField}) 966 pkColumn2 := common.GenColumnData(0, 10, entity.FieldTypeInt64, common.DefaultIntFieldName) 967 common.CheckQueryResult(t, queryRes, []entity.Column{pkColumn2, dynamicColumn}) 968 } 969 970 // test query with invalid expr 971 func TestQueryInvalidExpr(t *testing.T) { 972 t.Parallel() 973 ctx := createContext(t, time.Second*common.DefaultTimeout) 974 // connect 975 mc := createMilvusClient(ctx, t) 976 977 // create collection 978 cp := CollectionParams{ 979 CollectionFieldsType: Int64FloatVecJSON, 980 AutoID: false, 981 EnableDynamicField: true, 982 ShardsNum: common.DefaultShards, 983 Dim: common.DefaultDim, 984 } 985 collName := createCollection(ctx, t, mc, cp) 986 987 // insert 988 dp := DataParams{ 989 CollectionName: collName, 990 PartitionName: "", 991 CollectionFieldsType: Int64FloatVecJSON, 992 start: 0, 993 nb: common.DefaultNb, 994 dim: common.DefaultDim, 995 EnableDynamicField: true, 996 } 997 _, _ = insertData(ctx, t, mc, dp) 998 999 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1000 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1001 1002 // Load collection 1003 errLoad := mc.LoadCollection(ctx, collName, false) 1004 common.CheckErr(t, errLoad, true) 1005 1006 for _, _invalidExprs := range common.InvalidExpressions { 1007 _, err := mc.Query(ctx, collName, 1008 []string{common.DefaultPartition}, 1009 _invalidExprs.Expr, []string{common.DefaultJSONFieldName, common.DefaultDynamicNumberField}) 1010 common.CheckErr(t, err, _invalidExprs.ErrNil, _invalidExprs.ErrMsg) 1011 } 1012 } 1013 1014 // test query output invalid count(*) fields 1015 func TestQueryOutputInvalidOutputFieldCount(t *testing.T) { 1016 type invalidCountStruct struct { 1017 countField string 1018 errMsg string 1019 } 1020 t.Parallel() 1021 ctx := createContext(t, time.Second*common.DefaultTimeout) 1022 // connect 1023 mc := createMilvusClient(ctx, t) 1024 1025 // create, insert, index 1026 collName, _ := createCollectionWithDataIndex(ctx, t, mc, true, true, 1027 client.WithEnableDynamicSchema(false), client.WithConsistencyLevel(entity.ClStrong)) 1028 1029 // Load collection 1030 errLoad := mc.LoadCollection(ctx, collName, false) 1031 common.CheckErr(t, errLoad, true) 1032 1033 // invalid expr 1034 invalidOutputFieldCount := []invalidCountStruct{ 1035 {countField: "Count(*)", errMsg: "extra output fields [Count(*)] found and result does not dynamic field"}, 1036 {countField: "ccount(*)", errMsg: "field ccount(*) not exist"}, 1037 {countField: "count[*]", errMsg: "field count[*] not exist"}, 1038 {countField: "count", errMsg: "field count not exist"}, 1039 {countField: "count(**)", errMsg: "field count(**) not exist"}, 1040 } 1041 for _, invalidCount := range invalidOutputFieldCount { 1042 queryExpr := fmt.Sprintf("%s >= 0", common.DefaultIntFieldName) 1043 1044 //query with empty output fields []string{}-> output "int64" 1045 _, err := mc.Query( 1046 ctx, collName, []string{common.DefaultPartition}, 1047 queryExpr, []string{invalidCount.countField}) 1048 common.CheckErr(t, err, false, invalidCount.errMsg) 1049 } 1050 } 1051 1052 // test query count* after insert -> delete -> upsert -> compact 1053 func TestQueryCountAfterDml(t *testing.T) { 1054 ctx := createContext(t, time.Second*common.DefaultTimeout) 1055 // connect 1056 mc := createMilvusClient(ctx, t) 1057 1058 // create collection 1059 cp := CollectionParams{ 1060 CollectionFieldsType: Int64FloatVecJSON, 1061 AutoID: false, 1062 EnableDynamicField: true, 1063 ShardsNum: common.DefaultShards, 1064 Dim: common.DefaultDim, 1065 } 1066 collName := createCollection(ctx, t, mc, cp, client.WithConsistencyLevel(entity.ClStrong)) 1067 1068 // insert 1069 dp := DataParams{ 1070 CollectionName: collName, 1071 PartitionName: "", 1072 CollectionFieldsType: Int64FloatVecJSON, 1073 start: 0, 1074 nb: common.DefaultNb, 1075 dim: common.DefaultDim, 1076 EnableDynamicField: true, 1077 } 1078 _, _ = insertData(ctx, t, mc, dp) 1079 1080 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1081 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1082 1083 // Load collection 1084 errLoad := mc.LoadCollection(ctx, collName, false) 1085 common.CheckErr(t, errLoad, true) 1086 1087 // count* 1088 countQuery, _ := mc.Query(ctx, collName, []string{common.DefaultPartition}, "", []string{common.QueryCountFieldName}) 1089 require.Equal(t, int64(common.DefaultNb), countQuery.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 1090 1091 //inert 1000 entities -> count* 1092 insertNb := 1000 1093 dpInsert := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVecJSON, 1094 start: common.DefaultNb, nb: insertNb, dim: common.DefaultDim, EnableDynamicField: true} 1095 insertData(ctx, t, mc, dpInsert) 1096 countAfterInsert, _ := mc.Query(ctx, collName, []string{common.DefaultPartition}, "", []string{common.QueryCountFieldName}) 1097 require.Equal(t, int64(common.DefaultNb+insertNb), countAfterInsert.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 1098 1099 // delete 1000 entities -> count* 1100 mc.Delete(ctx, collName, common.DefaultPartition, fmt.Sprintf("%s < 1000 ", common.DefaultIntFieldName)) 1101 countAfterDelete, _ := mc.Query(ctx, collName, []string{common.DefaultPartition}, "", []string{common.QueryCountFieldName}) 1102 require.Equal(t, int64(common.DefaultNb), countAfterDelete.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 1103 1104 // upsert deleted 100 entities -> count* 1105 upsertNb := 100 1106 intColumn, floatColumn, vecColumn := common.GenDefaultColumnData(0, upsertNb, common.DefaultDim) 1107 jsonColumn := common.GenDefaultJSONData(common.DefaultJSONFieldName, 0, upsertNb) 1108 mc.Upsert(ctx, collName, "", intColumn, floatColumn, vecColumn, jsonColumn) 1109 countAfterUpsert, _ := mc.Query(ctx, collName, []string{common.DefaultPartition}, "", []string{common.QueryCountFieldName}) 1110 require.Equal(t, int64(common.DefaultNb+upsertNb), countAfterUpsert.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 1111 1112 // upsert existed 100 entities -> count* 1113 intColumn, floatColumn, vecColumn = common.GenDefaultColumnData(common.DefaultNb, upsertNb, common.DefaultDim) 1114 jsonColumn = common.GenDefaultJSONData(common.DefaultJSONFieldName, common.DefaultNb, upsertNb) 1115 mc.Upsert(ctx, collName, "", intColumn, floatColumn, vecColumn, jsonColumn) 1116 countAfterUpsert2, _ := mc.Query(ctx, collName, []string{common.DefaultPartition}, "", []string{common.QueryCountFieldName}) 1117 require.Equal(t, int64(common.DefaultNb+upsertNb), countAfterUpsert2.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 1118 1119 // compact -> count(*) 1120 _, err := mc.Compact(ctx, collName, time.Second*60) 1121 common.CheckErr(t, err, true) 1122 countAfterCompact, _ := mc.Query(ctx, collName, []string{common.DefaultPartition}, "", []string{common.QueryCountFieldName}) 1123 require.Equal(t, int64(common.DefaultNb+upsertNb), countAfterCompact.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 1124 } 1125 1126 func TestQuerySparseVector(t *testing.T) { 1127 t.Parallel() 1128 idxInverted := entity.NewGenericIndex(common.DefaultSparseVecFieldName, "SPARSE_INVERTED_INDEX", map[string]string{"drop_ratio_build": "0.2", "metric_type": "IP"}) 1129 idxWand := entity.NewGenericIndex(common.DefaultSparseVecFieldName, "SPARSE_WAND", map[string]string{"drop_ratio_build": "0.3", "metric_type": "IP"}) 1130 for _, idx := range []entity.Index{idxInverted, idxWand} { 1131 ctx := createContext(t, time.Second*common.DefaultTimeout*2) 1132 // connect 1133 mc := createMilvusClient(ctx, t) 1134 1135 // create -> insert [0, 3000) -> flush -> index -> load 1136 cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: false, 1137 ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: common.TestMaxLen} 1138 collName := createCollection(ctx, t, mc, cp) 1139 1140 // index 1141 idxHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1142 mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idxHnsw, false) 1143 mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, idx, false) 1144 1145 // insert 1146 intColumn, _, floatColumn := common.GenDefaultColumnData(0, common.DefaultNb, common.DefaultDim) 1147 varColumn := common.GenColumnData(0, common.DefaultNb, entity.FieldTypeVarChar, common.DefaultVarcharFieldName) 1148 sparseColumn := common.GenColumnData(0, common.DefaultNb, entity.FieldTypeSparseVector, common.DefaultSparseVecFieldName, common.WithSparseVectorLen(20)) 1149 mc.Insert(ctx, collName, "", intColumn, varColumn, floatColumn, sparseColumn) 1150 mc.Flush(ctx, collName, false) 1151 mc.LoadCollection(ctx, collName, false) 1152 1153 // count(*) 1154 countRes, _ := mc.Query(ctx, collName, []string{}, fmt.Sprintf("%s >=0", common.DefaultIntFieldName), []string{common.QueryCountFieldName}) 1155 require.Equal(t, int64(common.DefaultNb), countRes.GetColumn(common.QueryCountFieldName).(*entity.ColumnInt64).Data()[0]) 1156 1157 // query 1158 queryResult, err := mc.Query(ctx, collName, []string{}, fmt.Sprintf("%s in [0, 1]", common.DefaultIntFieldName), []string{"*"}) 1159 common.CheckErr(t, err, true) 1160 common.CheckOutputFields(t, queryResult, []string{common.DefaultIntFieldName, common.DefaultVarcharFieldName, common.DefaultFloatVecFieldName, common.DefaultSparseVecFieldName}) 1161 t.Log("https://github.com/milvus-io/milvus-sdk-go/issues/769") 1162 //common.CheckQueryResult(t, queryResult, []entity.Column{intColumn.Slice(0, 2), varColumn.Slice(0, 2), floatColumn.Slice(0, 2), sparseColumn.Slice(0, 2)}) 1163 } 1164 } 1165 1166 // test query iterator default 1167 func TestQueryIteratorDefault(t *testing.T) { 1168 ctx := createContext(t, time.Second*common.DefaultTimeout) 1169 // connect 1170 mc := createMilvusClient(ctx, t) 1171 1172 // create collection 1173 cp := CollectionParams{CollectionFieldsType: Int64FloatVec, AutoID: false, EnableDynamicField: true, 1174 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 1175 collName := createCollection(ctx, t, mc, cp) 1176 1177 // insert 1178 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVec, 1179 start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false} 1180 _, _ = insertData(ctx, t, mc, dp) 1181 1182 dp2 := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVec, 1183 start: common.DefaultNb, nb: common.DefaultNb * 2, dim: common.DefaultDim, EnableDynamicField: true, WithRows: true} 1184 _, _ = insertData(ctx, t, mc, dp2) 1185 1186 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1187 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1188 1189 // Load collection 1190 errLoad := mc.LoadCollection(ctx, collName, false) 1191 common.CheckErr(t, errLoad, true) 1192 1193 // query iterator with default batch 1194 itr, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName)) 1195 common.CheckErr(t, err, true) 1196 common.CheckQueryIteratorResult(ctx, t, itr, common.DefaultNb*3, common.WithExpBatchSize(common.GenBatchSizes(common.DefaultNb*3, common.DefaultBatchSize))) 1197 } 1198 1199 // test query iterator default 1200 func TestQueryIteratorHitEmpty(t *testing.T) { 1201 ctx := createContext(t, time.Second*common.DefaultTimeout) 1202 // connect 1203 mc := createMilvusClient(ctx, t) 1204 1205 // create collection 1206 cp := CollectionParams{CollectionFieldsType: Int64FloatVec, AutoID: false, EnableDynamicField: true, 1207 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 1208 collName := createCollection(ctx, t, mc, cp) 1209 1210 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1211 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1212 1213 // Load collection 1214 errLoad := mc.LoadCollection(ctx, collName, false) 1215 common.CheckErr(t, errLoad, true) 1216 1217 // query iterator with default batch 1218 itr, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName)) 1219 common.CheckErr(t, err, true) 1220 rs, err := itr.Next(ctx) 1221 require.Empty(t, rs) 1222 require.Error(t, err, io.EOF) 1223 common.CheckQueryIteratorResult(ctx, t, itr, 0, common.WithExpBatchSize(common.GenBatchSizes(0, common.DefaultBatchSize))) 1224 } 1225 1226 func TestQueryIteratorBatchSize(t *testing.T) { 1227 ctx := createContext(t, time.Second*common.DefaultTimeout) 1228 // connect 1229 mc := createMilvusClient(ctx, t) 1230 // create collection 1231 cp := CollectionParams{CollectionFieldsType: Int64FloatVec, AutoID: false, EnableDynamicField: true, 1232 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 1233 collName := createCollection(ctx, t, mc, cp) 1234 1235 // insert 1236 nb := 201 1237 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVec, 1238 start: 0, nb: nb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false} 1239 _, _ = insertData(ctx, t, mc, dp) 1240 1241 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1242 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1243 1244 // Load collection 1245 errLoad := mc.LoadCollection(ctx, collName, false) 1246 common.CheckErr(t, errLoad, true) 1247 1248 type batchStruct struct { 1249 batch int 1250 expBatchSize []int 1251 } 1252 batchStructs := []batchStruct{ 1253 {batch: nb / 2, expBatchSize: common.GenBatchSizes(nb, nb/2)}, 1254 {batch: nb, expBatchSize: common.GenBatchSizes(nb, nb)}, 1255 {batch: nb + 1, expBatchSize: common.GenBatchSizes(nb, nb+1)}, 1256 } 1257 1258 for _, _batchStruct := range batchStructs { 1259 // query iterator with default batch 1260 itr, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithBatchSize(_batchStruct.batch)) 1261 common.CheckErr(t, err, true) 1262 common.CheckQueryIteratorResult(ctx, t, itr, nb, common.WithExpBatchSize(_batchStruct.expBatchSize)) 1263 } 1264 } 1265 1266 func TestQueryIteratorOutputAllFields(t *testing.T) { 1267 t.Parallel() 1268 ctx := createContext(t, time.Second*common.DefaultTimeout) 1269 // connect 1270 mc := createMilvusClient(ctx, t) 1271 for _, dynamic := range [2]bool{false, true} { 1272 // create collection 1273 cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: dynamic, 1274 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 1275 collName := createCollection(ctx, t, mc, cp, client.WithConsistencyLevel(entity.ClStrong)) 1276 1277 // insert 1278 nb := 2501 1279 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields, 1280 start: 0, nb: nb, dim: common.DefaultDim, EnableDynamicField: dynamic, WithRows: false} 1281 insertData(ctx, t, mc, dp) 1282 1283 indexHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1284 indexBinary, _ := entity.NewIndexBinIvfFlat(entity.JACCARD, 64) 1285 for _, fieldName := range common.AllVectorsFieldsName { 1286 if fieldName == common.DefaultBinaryVecFieldName { 1287 mc.CreateIndex(ctx, collName, fieldName, indexBinary, false) 1288 } else { 1289 mc.CreateIndex(ctx, collName, fieldName, indexHnsw, false) 1290 } 1291 } 1292 1293 // Load collection 1294 errLoad := mc.LoadCollection(ctx, collName, false) 1295 common.CheckErr(t, errLoad, true) 1296 1297 // output * fields 1298 nbFilter := 1001 1299 batch := 500 1300 expr := fmt.Sprintf("%s < %d", common.DefaultIntFieldName, nbFilter) 1301 1302 itr, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithBatchSize(batch).WithOutputFields("*").WithExpr(expr)) 1303 common.CheckErr(t, err, true) 1304 allFields := common.GetAllFieldsName(dynamic, false) 1305 common.CheckQueryIteratorResult(ctx, t, itr, nbFilter, common.WithExpBatchSize(common.GenBatchSizes(nbFilter, batch)), common.WithExpOutputFields(allFields)) 1306 } 1307 } 1308 1309 func TestQueryIteratorOutputSparseFieldsRows(t *testing.T) { 1310 t.Parallel() 1311 ctx := createContext(t, time.Second*common.DefaultTimeout) 1312 // connect 1313 mc := createMilvusClient(ctx, t) 1314 for _, withRows := range [2]bool{true, false} { 1315 // create collection 1316 cp := CollectionParams{CollectionFieldsType: Int64VarcharSparseVec, AutoID: false, EnableDynamicField: true, 1317 ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxLength: common.TestMaxLen} 1318 collName := createCollection(ctx, t, mc, cp) 1319 1320 // insert 1321 nb := 2501 1322 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64VarcharSparseVec, 1323 start: 0, nb: nb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: withRows, maxLenSparse: 1000} 1324 _, _ = insertData(ctx, t, mc, dp) 1325 1326 indexHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1327 indexSparse, _ := entity.NewIndexSparseInverted(entity.IP, 0.1) 1328 mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, indexHnsw, false) 1329 mc.CreateIndex(ctx, collName, common.DefaultSparseVecFieldName, indexSparse, false) 1330 1331 // Load collection 1332 errLoad := mc.LoadCollection(ctx, collName, false) 1333 common.CheckErr(t, errLoad, true) 1334 1335 // output * fields 1336 itr, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithBatchSize(400).WithOutputFields("*")) 1337 common.CheckErr(t, err, true) 1338 fields := []string{common.DefaultIntFieldName, common.DefaultVarcharFieldName, common.DefaultFloatVecFieldName, common.DefaultSparseVecFieldName, common.DefaultDynamicFieldName} 1339 common.CheckQueryIteratorResult(ctx, t, itr, nb, common.WithExpBatchSize(common.GenBatchSizes(nb, 400)), common.WithExpOutputFields(fields)) 1340 } 1341 } 1342 1343 // test query iterator with non-existed collection/partition name, invalid batch size 1344 func TestQueryIteratorInvalid(t *testing.T) { 1345 ctx := createContext(t, time.Second*common.DefaultTimeout) 1346 // connect 1347 mc := createMilvusClient(ctx, t) 1348 // create collection 1349 cp := CollectionParams{CollectionFieldsType: Int64FloatVec, AutoID: false, EnableDynamicField: false, 1350 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 1351 collName := createCollection(ctx, t, mc, cp) 1352 1353 // insert 1354 nb := 201 1355 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVec, 1356 start: 0, nb: nb, dim: common.DefaultDim, EnableDynamicField: false, WithRows: false} 1357 _, _ = insertData(ctx, t, mc, dp) 1358 1359 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1360 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1361 1362 // Load collection 1363 errLoad := mc.LoadCollection(ctx, collName, false) 1364 common.CheckErr(t, errLoad, true) 1365 1366 // query iterator with not existed collection name 1367 _, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption("aaa")) 1368 common.CheckErr(t, err, false, "can't find collection") 1369 1370 // query iterator with not existed partition name 1371 _, errPar := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithPartitions("aaa")) 1372 common.CheckErr(t, errPar, false, "partition name aaa not found") 1373 1374 // query iterator with not existed partition name 1375 _, errPar = mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithPartitions("aaa", common.DefaultPartition)) 1376 common.CheckErr(t, errPar, false, "partition name aaa not found") 1377 1378 _, errOutput := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithOutputFields(common.QueryCountFieldName)) 1379 common.CheckErr(t, errOutput, false, "count entities with pagination is not allowed") 1380 1381 // query iterator with invalid batch size 1382 for _, batch := range []int{-1, 0} { 1383 // query iterator with default batch 1384 _, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithBatchSize(batch)) 1385 common.CheckErr(t, err, false, "batch size cannot less than 1") 1386 } 1387 } 1388 1389 // query iterator with invalid expr 1390 func TestQueryIteratorInvalidExpr(t *testing.T) { 1391 ctx := createContext(t, time.Second*common.DefaultTimeout) 1392 // connect 1393 mc := createMilvusClient(ctx, t) 1394 1395 // create collection 1396 cp := CollectionParams{CollectionFieldsType: Int64FloatVecJSON, AutoID: false, EnableDynamicField: true, 1397 ShardsNum: common.DefaultShards, Dim: common.DefaultDim, 1398 } 1399 collName := createCollection(ctx, t, mc, cp) 1400 1401 // insert 1402 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVecJSON, 1403 start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, 1404 } 1405 _, _ = insertData(ctx, t, mc, dp) 1406 1407 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1408 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1409 1410 // Load collection 1411 errLoad := mc.LoadCollection(ctx, collName, false) 1412 common.CheckErr(t, errLoad, true) 1413 1414 for _, _invalidExprs := range common.InvalidExpressions { 1415 _, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithExpr(_invalidExprs.Expr)) 1416 common.CheckErr(t, err, _invalidExprs.ErrNil, _invalidExprs.ErrMsg) 1417 } 1418 } 1419 1420 // test query iterator with non-existed field when dynamic or not 1421 func TestQueryIteratorOutputFieldDynamic(t *testing.T) { 1422 ctx := createContext(t, time.Second*common.DefaultTimeout) 1423 // connect 1424 mc := createMilvusClient(ctx, t) 1425 for _, dynamic := range [2]bool{true, false} { 1426 // create collection 1427 cp := CollectionParams{CollectionFieldsType: Int64FloatVec, AutoID: false, EnableDynamicField: dynamic, 1428 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 1429 collName := createCollection(ctx, t, mc, cp) 1430 // insert 1431 nb := 201 1432 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVec, 1433 start: 0, nb: nb, dim: common.DefaultDim, EnableDynamicField: dynamic, WithRows: false} 1434 _, _ = insertData(ctx, t, mc, dp) 1435 1436 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1437 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1438 1439 // Load collection 1440 errLoad := mc.LoadCollection(ctx, collName, false) 1441 common.CheckErr(t, errLoad, true) 1442 1443 // query iterator with not existed output fields: if dynamic, non-existent field are equivalent to dynamic field 1444 itr, errOutput := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithOutputFields("aaa")) 1445 if dynamic { 1446 common.CheckErr(t, errOutput, true) 1447 expFields := []string{common.DefaultIntFieldName, common.DefaultDynamicFieldName} 1448 common.CheckQueryIteratorResult(ctx, t, itr, nb, common.WithExpBatchSize(common.GenBatchSizes(nb, common.DefaultBatchSize)), common.WithExpOutputFields(expFields)) 1449 } else { 1450 common.CheckErr(t, errOutput, false, "field aaa not exist") 1451 } 1452 } 1453 } 1454 1455 func TestQueryIteratorExpr(t *testing.T) { 1456 //t.Log("https://github.com/milvus-io/milvus-sdk-go/issues/756") 1457 type exprCount struct { 1458 expr string 1459 count int 1460 } 1461 capacity := common.TestCapacity 1462 exprLimits := []exprCount{ 1463 {expr: fmt.Sprintf("%s in [0, 1, 2]", common.DefaultIntFieldName), count: 3}, 1464 {expr: fmt.Sprintf("%s >= 1000 || %s > 2000", common.DefaultIntFieldName, common.DefaultIntFieldName), count: 2000}, 1465 {expr: fmt.Sprintf("%s >= 1000 and %s < 2000", common.DefaultIntFieldName, common.DefaultIntFieldName), count: 1000}, 1466 1467 //json and dynamic field filter expr: == < in bool/ list/ int 1468 {expr: fmt.Sprintf("%s['number'] == 0", common.DefaultJSONFieldName), count: 1500 / 2}, 1469 {expr: fmt.Sprintf("%s['number'] < 100 and %s['number'] != 0", common.DefaultJSONFieldName, common.DefaultJSONFieldName), count: 50}, 1470 {expr: fmt.Sprintf("%s < 100", common.DefaultDynamicNumberField), count: 100}, 1471 {expr: "dynamicNumber % 2 == 0", count: 1500}, 1472 {expr: fmt.Sprintf("%s == false", common.DefaultDynamicBoolField), count: 2000}, 1473 {expr: fmt.Sprintf("%s in ['1', '2'] ", common.DefaultDynamicStringField), count: 2}, 1474 {expr: fmt.Sprintf("%s['string'] in ['1', '2', '5'] ", common.DefaultJSONFieldName), count: 3}, 1475 {expr: fmt.Sprintf("%s['list'] == [1, 2] ", common.DefaultJSONFieldName), count: 1}, 1476 {expr: fmt.Sprintf("%s['list'][0] < 10 ", common.DefaultJSONFieldName), count: 5}, 1477 {expr: fmt.Sprintf("%s[\"dynamicList\"] != [2, 3]", common.DefaultDynamicFieldName), count: 0}, 1478 1479 // json contains 1480 {expr: fmt.Sprintf("json_contains (%s['list'], 2)", common.DefaultJSONFieldName), count: 1}, 1481 {expr: fmt.Sprintf("json_contains (%s['number'], 0)", common.DefaultJSONFieldName), count: 0}, 1482 {expr: fmt.Sprintf("JSON_CONTAINS_ANY (%s['list'], [1, 3])", common.DefaultJSONFieldName), count: 2}, 1483 // string like 1484 {expr: "dynamicString like '1%' ", count: 1111}, 1485 1486 // key exist 1487 {expr: fmt.Sprintf("exists %s['list']", common.DefaultJSONFieldName), count: common.DefaultNb / 2}, 1488 {expr: fmt.Sprintf("exists a "), count: 0}, 1489 {expr: fmt.Sprintf("exists %s ", common.DefaultDynamicStringField), count: common.DefaultNb}, 1490 1491 // data type not match and no error 1492 {expr: fmt.Sprintf("%s['number'] == '0' ", common.DefaultJSONFieldName), count: 0}, 1493 1494 // json field 1495 {expr: fmt.Sprintf("%s >= 1500", common.DefaultJSONFieldName), count: 1500 / 2}, // json >= 1500 1496 {expr: fmt.Sprintf("%s > 1499.5", common.DefaultJSONFieldName), count: 1500 / 2}, // json >= 1500.0 1497 {expr: fmt.Sprintf("%s like '21%%'", common.DefaultJSONFieldName), count: 100 / 4}, // json like '21%' 1498 {expr: fmt.Sprintf("%s == [1503, 1504]", common.DefaultJSONFieldName), count: 1}, // json == [1,2] 1499 {expr: fmt.Sprintf("%s[0] > 1", common.DefaultJSONFieldName), count: 1500 / 4}, // json[0] > 1 1500 {expr: fmt.Sprintf("%s[0][0] > 1", common.DefaultJSONFieldName), count: 0}, // json == [1,2] 1501 {expr: fmt.Sprintf("%s[0] == false", common.DefaultBoolArrayField), count: common.DefaultNb / 2}, // array[0] == 1502 {expr: fmt.Sprintf("%s[0] > 0", common.DefaultInt64ArrayField), count: common.DefaultNb - 1}, // array[0] > 1503 {expr: fmt.Sprintf("%s[0] > 0", common.DefaultInt8ArrayField), count: 1524}, // array[0] > int8 range: [-128, 127] 1504 {expr: fmt.Sprintf("array_contains (%s, %d)", common.DefaultInt16ArrayField, capacity), count: capacity}, // array_contains(array, 1) 1505 {expr: fmt.Sprintf("json_contains (%s, 1)", common.DefaultInt32ArrayField), count: 2}, // json_contains(array, 1) 1506 {expr: fmt.Sprintf("array_contains (%s, 1000000)", common.DefaultInt32ArrayField), count: 0}, // array_contains(array, 1) 1507 {expr: fmt.Sprintf("json_contains_all (%s, [90, 91])", common.DefaultInt64ArrayField), count: 91}, // json_contains_all(array, [x]) 1508 {expr: fmt.Sprintf("json_contains_any (%s, [0, 100, 10])", common.DefaultFloatArrayField), count: 101}, // json_contains_any (array, [x]) 1509 {expr: fmt.Sprintf("%s == [0, 1]", common.DefaultDoubleArrayField), count: 0}, // array == 1510 {expr: fmt.Sprintf("array_length(%s) == %d", common.DefaultDoubleArrayField, capacity), count: common.DefaultNb}, // array_length 1511 } 1512 1513 ctx := createContext(t, time.Second*common.DefaultTimeout) 1514 // connect 1515 mc := createMilvusClient(ctx, t) 1516 1517 // create collection 1518 cp := CollectionParams{CollectionFieldsType: AllFields, AutoID: false, EnableDynamicField: true, 1519 ShardsNum: common.DefaultShards, Dim: common.DefaultDim, MaxCapacity: common.TestCapacity} 1520 collName := createCollection(ctx, t, mc, cp, client.WithConsistencyLevel(entity.ClStrong)) 1521 1522 // insert 1523 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: AllFields, 1524 start: 0, nb: common.DefaultNb, dim: common.DefaultDim, EnableDynamicField: true, WithRows: false} 1525 _, err := insertData(ctx, t, mc, dp, common.WithArrayCapacity(common.TestCapacity)) 1526 common.CheckErr(t, err, true) 1527 mc.Flush(ctx, collName, false) 1528 1529 indexHnsw, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1530 indexBinary, _ := entity.NewIndexBinIvfFlat(entity.JACCARD, 64) 1531 for _, fieldName := range common.AllVectorsFieldsName { 1532 if fieldName == common.DefaultBinaryVecFieldName { 1533 mc.CreateIndex(ctx, collName, fieldName, indexBinary, false) 1534 } else { 1535 mc.CreateIndex(ctx, collName, fieldName, indexHnsw, false) 1536 } 1537 } 1538 1539 // Load collection 1540 errLoad := mc.LoadCollection(ctx, collName, false) 1541 common.CheckErr(t, errLoad, true) 1542 batch := 500 1543 1544 for _, exprLimit := range exprLimits { 1545 log.Printf("case expr is: %s, limit=%d", exprLimit.expr, exprLimit.count) 1546 itr, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithBatchSize(batch).WithExpr(exprLimit.expr)) 1547 common.CheckErr(t, err, true) 1548 common.CheckQueryIteratorResult(ctx, t, itr, exprLimit.count, common.WithExpBatchSize(common.GenBatchSizes(exprLimit.count, batch))) 1549 } 1550 } 1551 1552 // test query iterator with partition 1553 func TestQueryIteratorPartitions(t *testing.T) { 1554 ctx := createContext(t, time.Second*common.DefaultTimeout) 1555 // connect 1556 mc := createMilvusClient(ctx, t) 1557 // create collection 1558 cp := CollectionParams{CollectionFieldsType: Int64FloatVec, AutoID: false, EnableDynamicField: false, 1559 ShardsNum: common.DefaultShards, Dim: common.DefaultDim} 1560 collName := createCollection(ctx, t, mc, cp) 1561 pName := "p1" 1562 err := mc.CreatePartition(ctx, collName, pName) 1563 common.CheckErr(t, err, true) 1564 1565 // insert [0, nb) into partition: _default 1566 nb := 1500 1567 dp := DataParams{CollectionName: collName, PartitionName: "", CollectionFieldsType: Int64FloatVec, 1568 start: 0, nb: nb, dim: common.DefaultDim, EnableDynamicField: false, WithRows: false} 1569 _, _ = insertData(ctx, t, mc, dp) 1570 // insert [nb, nb*2) into partition: p1 1571 dp1 := DataParams{CollectionName: collName, PartitionName: pName, CollectionFieldsType: Int64FloatVec, 1572 start: nb, nb: nb, dim: common.DefaultDim, EnableDynamicField: false, WithRows: false} 1573 _, _ = insertData(ctx, t, mc, dp1) 1574 1575 idx, _ := entity.NewIndexHNSW(entity.L2, 8, 96) 1576 _ = mc.CreateIndex(ctx, collName, common.DefaultFloatVecFieldName, idx, false) 1577 1578 // Load collection 1579 errLoad := mc.LoadCollection(ctx, collName, false) 1580 common.CheckErr(t, errLoad, true) 1581 1582 // query iterator with partition 1583 expr := fmt.Sprintf("%s < %d", common.DefaultIntFieldName, nb) 1584 mParLimit := map[string]int{ 1585 common.DefaultPartition: nb, 1586 pName: 0, 1587 } 1588 for par, limit := range mParLimit { 1589 itr, err := mc.QueryIterator(ctx, client.NewQueryIteratorOption(collName).WithExpr(expr).WithPartitions(par)) 1590 common.CheckErr(t, err, true) 1591 common.CheckQueryIteratorResult(ctx, t, itr, limit, common.WithExpBatchSize(common.GenBatchSizes(limit, common.DefaultBatchSize))) 1592 } 1593 } 1594 1595 // TODO offset and limit 1596 // TODO consistency level 1597 // TODO ignore growing