github.com/weaviate/weaviate@v1.24.6/usecases/traverser/traverser_explore_concepts_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package traverser 13 14 import ( 15 "context" 16 "testing" 17 18 "github.com/go-openapi/strfmt" 19 "github.com/sirupsen/logrus/hooks/test" 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 "github.com/weaviate/weaviate/entities/search" 23 "github.com/weaviate/weaviate/entities/searchparams" 24 "github.com/weaviate/weaviate/usecases/config" 25 ) 26 27 func Test_ExploreConcepts(t *testing.T) { 28 t.Run("without any near searchers", func(t *testing.T) { 29 authorizer := &fakeAuthorizer{} 30 locks := &fakeLocks{} 31 logger, _ := test.NewNullLogger() 32 vectorSearcher := &fakeVectorSearcher{} 33 log, _ := test.NewNullLogger() 34 metrics := &fakeMetrics{} 35 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 36 schemaGetter := &fakeSchemaGetter{} 37 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 38 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 39 params := ExploreParams{} 40 41 _, err := traverser.Explore(context.Background(), nil, params) 42 assert.Contains(t, err.Error(), "received no search params") 43 }) 44 45 t.Run("with two searchers set at the same time", func(t *testing.T) { 46 authorizer := &fakeAuthorizer{} 47 locks := &fakeLocks{} 48 logger, _ := test.NewNullLogger() 49 vectorSearcher := &fakeVectorSearcher{} 50 log, _ := test.NewNullLogger() 51 metrics := &fakeMetrics{} 52 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 53 schemaGetter := &fakeSchemaGetter{} 54 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 55 vectorSearcher, explorer, schemaGetter, nil, nil, -1) 56 params := ExploreParams{ 57 NearVector: &searchparams.NearVector{}, 58 ModuleParams: map[string]interface{}{ 59 "nearCustomText": nil, 60 }, 61 } 62 63 _, err := traverser.Explore(context.Background(), nil, params) 64 assert.Contains(t, err.Error(), "parameters which are conflicting") 65 }) 66 t.Run("nearCustomText with no movements set", func(t *testing.T) { 67 authorizer := &fakeAuthorizer{} 68 locks := &fakeLocks{} 69 logger, _ := test.NewNullLogger() 70 vectorSearcher := &fakeVectorSearcher{} 71 log, _ := test.NewNullLogger() 72 metrics := &fakeMetrics{} 73 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 74 schemaGetter := &fakeSchemaGetter{} 75 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 76 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 77 params := ExploreParams{ 78 ModuleParams: map[string]interface{}{ 79 "nearCustomText": extractNearCustomTextParam(map[string]interface{}{ 80 "concepts": []interface{}{"a search term", "another"}, 81 }), 82 }, 83 } 84 vectorSearcher.results = []search.Result{ 85 { 86 ClassName: "BestClass", 87 ID: "123-456-789", 88 Certainty: 0.5, 89 Dist: 0.5, 90 Dims: 128, 91 }, 92 { 93 ClassName: "AnAction", 94 ID: "987-654-321", 95 Certainty: 0.5, 96 Dist: 0.5, 97 Dims: 128, 98 }, 99 } 100 101 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearCustomText", 128) 102 103 res, err := traverser.Explore(context.Background(), nil, params) 104 require.Nil(t, err) 105 assert.Equal(t, []search.Result{ 106 { 107 ClassName: "BestClass", 108 ID: "123-456-789", 109 Beacon: "weaviate://localhost/BestClass/123-456-789", 110 Certainty: 0.5, 111 Dist: 0.5, 112 Dims: 128, 113 }, 114 { 115 ClassName: "AnAction", 116 ID: "987-654-321", 117 Beacon: "weaviate://localhost/AnAction/987-654-321", 118 Certainty: 0.5, 119 Dist: 0.5, 120 Dims: 128, 121 }, 122 }, res) 123 124 assert.Equal(t, []float32{1, 2, 3}, vectorSearcher.calledWithVector) 125 assert.Equal(t, 20, vectorSearcher.calledWithLimit, 126 "uses the default limit if not explicitly set") 127 }) 128 129 t.Run("nearCustomText without optional params", func(t *testing.T) { 130 authorizer := &fakeAuthorizer{} 131 locks := &fakeLocks{} 132 logger, _ := test.NewNullLogger() 133 vectorSearcher := &fakeVectorSearcher{} 134 log, _ := test.NewNullLogger() 135 metrics := &fakeMetrics{} 136 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 137 schemaGetter := &fakeSchemaGetter{} 138 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 139 vectorSearcher, explorer, schemaGetter, nil, nil, -1) 140 params := ExploreParams{ 141 NearVector: &searchparams.NearVector{ 142 Vector: []float32{7.8, 9}, 143 }, 144 } 145 vectorSearcher.results = []search.Result{ 146 { 147 ClassName: "BestClass", 148 ID: "123-456-789", 149 Certainty: 0.5, 150 Dist: 0.5, 151 Dims: 128, 152 }, 153 { 154 ClassName: "AnAction", 155 ID: "987-654-321", 156 Certainty: 0.5, 157 Dist: 0.5, 158 Dims: 128, 159 }, 160 } 161 162 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearVector", 128) 163 res, err := traverser.Explore(context.Background(), nil, params) 164 require.Nil(t, err) 165 assert.Equal(t, []search.Result{ 166 { 167 ClassName: "BestClass", 168 ID: "123-456-789", 169 Beacon: "weaviate://localhost/BestClass/123-456-789", 170 Certainty: 0.5, 171 Dist: 0.5, 172 Dims: 128, 173 }, 174 { 175 ClassName: "AnAction", 176 ID: "987-654-321", 177 Beacon: "weaviate://localhost/AnAction/987-654-321", 178 Certainty: 0.5, 179 Dist: 0.5, 180 Dims: 128, 181 }, 182 }, res) 183 184 assert.Equal(t, []float32{7.8, 9}, vectorSearcher.calledWithVector) 185 assert.Equal(t, 20, vectorSearcher.calledWithLimit, 186 "uses the default limit if not explicitly set") 187 }) 188 189 t.Run("nearObject with id param", func(t *testing.T) { 190 authorizer := &fakeAuthorizer{} 191 locks := &fakeLocks{} 192 logger, _ := test.NewNullLogger() 193 vectorSearcher := &fakeVectorSearcher{} 194 log, _ := test.NewNullLogger() 195 metrics := &fakeMetrics{} 196 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 197 schemaGetter := &fakeSchemaGetter{} 198 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 199 vectorSearcher, explorer, schemaGetter, nil, nil, -1) 200 params := ExploreParams{ 201 NearObject: &searchparams.NearObject{ 202 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 203 }, 204 } 205 searchRes := search.Result{ 206 ClassName: "BestClass", 207 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 208 } 209 vectorSearcher. 210 On("ObjectsByID", strfmt.UUID("bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a")). 211 Return(search.Results{searchRes}, nil) 212 vectorSearcher.results = []search.Result{ 213 { 214 ClassName: "BestClass", 215 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 216 Certainty: 0.5, 217 Dist: 0.5, 218 Dims: 128, 219 }, 220 { 221 ClassName: "AnAction", 222 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23b", 223 Certainty: 0.5, 224 Dist: 0.5, 225 Dims: 128, 226 }, 227 } 228 229 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearObject", 128) 230 res, err := traverser.Explore(context.Background(), nil, params) 231 require.Nil(t, err) 232 assert.Equal(t, []search.Result{ 233 { 234 ClassName: "BestClass", 235 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 236 Beacon: "weaviate://localhost/BestClass/bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 237 Certainty: 0.5, 238 Dist: 0.5, 239 Dims: 128, 240 }, 241 { 242 ClassName: "AnAction", 243 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23b", 244 Beacon: "weaviate://localhost/AnAction/bd3d1560-3f0e-4b39-9d62-38b4a3c4f23b", 245 Certainty: 0.5, 246 Dist: 0.5, 247 Dims: 128, 248 }, 249 }, res) 250 251 assert.Equal(t, 20, vectorSearcher.calledWithLimit, 252 "uses the default limit if not explicitly set") 253 }) 254 255 t.Run("nearObject with beacon param", func(t *testing.T) { 256 authorizer := &fakeAuthorizer{} 257 locks := &fakeLocks{} 258 logger, _ := test.NewNullLogger() 259 vectorSearcher := &fakeVectorSearcher{} 260 log, _ := test.NewNullLogger() 261 metrics := &fakeMetrics{} 262 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 263 schemaGetter := &fakeSchemaGetter{} 264 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 265 vectorSearcher, explorer, schemaGetter, nil, nil, -1) 266 params := ExploreParams{ 267 NearObject: &searchparams.NearObject{ 268 Beacon: "weaviate://localhost/bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 269 }, 270 } 271 searchRes := search.Result{ 272 ClassName: "BestClass", 273 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 274 } 275 vectorSearcher. 276 On("ObjectsByID", strfmt.UUID("bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a")). 277 Return(search.Results{searchRes}, nil) 278 vectorSearcher.results = []search.Result{ 279 { 280 ClassName: "BestClass", 281 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 282 Certainty: 0.5, 283 Dist: 0.5, 284 Dims: 128, 285 }, 286 { 287 ClassName: "AnAction", 288 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23b", 289 Certainty: 0.5, 290 Dist: 0.5, 291 Dims: 128, 292 }, 293 } 294 295 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearObject", 128) 296 res, err := traverser.Explore(context.Background(), nil, params) 297 require.Nil(t, err) 298 assert.Equal(t, []search.Result{ 299 { 300 ClassName: "BestClass", 301 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 302 Beacon: "weaviate://localhost/BestClass/bd3d1560-3f0e-4b39-9d62-38b4a3c4f23a", 303 Certainty: 0.5, 304 Dist: 0.5, 305 Dims: 128, 306 }, 307 { 308 ClassName: "AnAction", 309 ID: "bd3d1560-3f0e-4b39-9d62-38b4a3c4f23b", 310 Beacon: "weaviate://localhost/AnAction/bd3d1560-3f0e-4b39-9d62-38b4a3c4f23b", 311 Certainty: 0.5, 312 Dist: 0.5, 313 Dims: 128, 314 }, 315 }, res) 316 317 assert.Equal(t, 20, vectorSearcher.calledWithLimit, 318 "uses the default limit if not explicitly set") 319 }) 320 321 t.Run("nearCustomText with limit and distance set", func(t *testing.T) { 322 authorizer := &fakeAuthorizer{} 323 locks := &fakeLocks{} 324 logger, _ := test.NewNullLogger() 325 vectorSearcher := &fakeVectorSearcher{} 326 log, _ := test.NewNullLogger() 327 metrics := &fakeMetrics{} 328 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 329 schemaGetter := &fakeSchemaGetter{} 330 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 331 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 332 params := ExploreParams{ 333 Limit: 100, 334 NearVector: &searchparams.NearVector{ 335 Vector: []float32{7.8, 9}, 336 Distance: 0.2, 337 WithDistance: true, 338 }, 339 } 340 vectorSearcher.results = []search.Result{ 341 { 342 ClassName: "BestClass", 343 ID: "123-456-789", 344 Dist: 0.4, 345 Dims: 128, 346 }, 347 { 348 ClassName: "AnAction", 349 ID: "987-654-321", 350 Dist: 0.4, 351 Dims: 128, 352 }, 353 } 354 355 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearVector", 128) 356 res, err := traverser.Explore(context.Background(), nil, params) 357 require.Nil(t, err) 358 assert.Equal(t, []search.Result{}, res) // certainty not matched 359 360 assert.Equal(t, []float32{7.8, 9}, vectorSearcher.calledWithVector) 361 assert.Equal(t, 100, vectorSearcher.calledWithLimit, 362 "uses the default limit if not explicitly set") 363 }) 364 365 t.Run("nearCustomText with limit and certainty set", func(t *testing.T) { 366 authorizer := &fakeAuthorizer{} 367 locks := &fakeLocks{} 368 logger, _ := test.NewNullLogger() 369 vectorSearcher := &fakeVectorSearcher{} 370 log, _ := test.NewNullLogger() 371 metrics := &fakeMetrics{} 372 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 373 schemaGetter := &fakeSchemaGetter{} 374 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 375 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 376 params := ExploreParams{ 377 Limit: 100, 378 NearVector: &searchparams.NearVector{ 379 Vector: []float32{7.8, 9}, 380 Certainty: 0.8, 381 }, 382 } 383 vectorSearcher.results = []search.Result{ 384 { 385 ClassName: "BestClass", 386 ID: "123-456-789", 387 Dims: 128, 388 }, 389 { 390 ClassName: "AnAction", 391 ID: "987-654-321", 392 Dims: 128, 393 }, 394 } 395 396 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearVector", 128) 397 res, err := traverser.Explore(context.Background(), nil, params) 398 require.Nil(t, err) 399 assert.Equal(t, []search.Result{}, res) // certainty not matched 400 401 assert.Equal(t, []float32{7.8, 9}, vectorSearcher.calledWithVector) 402 assert.Equal(t, 100, vectorSearcher.calledWithLimit, 403 "uses the default limit if not explicitly set") 404 }) 405 406 t.Run("nearCustomText with minimum distance set to 0.4", func(t *testing.T) { 407 authorizer := &fakeAuthorizer{} 408 locks := &fakeLocks{} 409 logger, _ := test.NewNullLogger() 410 vectorSearcher := &fakeVectorSearcher{} 411 log, _ := test.NewNullLogger() 412 metrics := &fakeMetrics{} 413 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 414 schemaGetter := &fakeSchemaGetter{} 415 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 416 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 417 params := ExploreParams{ 418 ModuleParams: map[string]interface{}{ 419 "nearCustomText": extractNearCustomTextParam(map[string]interface{}{ 420 "concepts": []interface{}{"a search term", "another"}, 421 "distance": float64(0.4), 422 }), 423 }, 424 } 425 vectorSearcher.results = []search.Result{} 426 427 res, err := traverser.Explore(context.Background(), nil, params) 428 require.Nil(t, err) 429 assert.Equal(t, []search.Result{}, res, "empty result because distance is not met") 430 assert.Equal(t, []float32{1, 2, 3}, vectorSearcher.calledWithVector) 431 assert.Equal(t, 20, vectorSearcher.calledWithLimit, 432 "uses the default limit if not explicitly set") 433 }) 434 435 t.Run("nearCustomText with minimum certainty set to 0.6", func(t *testing.T) { 436 authorizer := &fakeAuthorizer{} 437 locks := &fakeLocks{} 438 logger, _ := test.NewNullLogger() 439 vectorSearcher := &fakeVectorSearcher{} 440 log, _ := test.NewNullLogger() 441 metrics := &fakeMetrics{} 442 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 443 schemaGetter := &fakeSchemaGetter{} 444 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 445 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 446 params := ExploreParams{ 447 ModuleParams: map[string]interface{}{ 448 "nearCustomText": extractNearCustomTextParam(map[string]interface{}{ 449 "concepts": []interface{}{"a search term", "another"}, 450 "certainty": float64(0.6), 451 }), 452 }, 453 } 454 vectorSearcher.results = []search.Result{ 455 { 456 ClassName: "BestClass", 457 ID: "123-456-789", 458 Dims: 128, 459 }, 460 { 461 ClassName: "AnAction", 462 ID: "987-654-321", 463 Dims: 128, 464 }, 465 } 466 467 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearCustomText", 128) 468 res, err := traverser.Explore(context.Background(), nil, params) 469 require.Nil(t, err) 470 assert.Equal(t, []search.Result{}, res, "empty result because certainty is not met") 471 assert.Equal(t, []float32{1, 2, 3}, vectorSearcher.calledWithVector) 472 assert.Equal(t, 20, vectorSearcher.calledWithLimit, 473 "uses the default limit if not explicitly set") 474 }) 475 476 t.Run("near text with movements set", func(t *testing.T) { 477 authorizer := &fakeAuthorizer{} 478 locks := &fakeLocks{} 479 logger, _ := test.NewNullLogger() 480 vectorSearcher := &fakeVectorSearcher{} 481 log, _ := test.NewNullLogger() 482 metrics := &fakeMetrics{} 483 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 484 schemaGetter := &fakeSchemaGetter{} 485 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 486 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 487 params := ExploreParams{ 488 Limit: 100, 489 ModuleParams: map[string]interface{}{ 490 "nearCustomText": extractNearCustomTextParam(map[string]interface{}{ 491 "concepts": []interface{}{"a search term", "another"}, 492 "moveTo": map[string]interface{}{ 493 "concepts": []interface{}{"foo"}, 494 "force": float64(0.7), 495 }, 496 "moveAwayFrom": map[string]interface{}{ 497 "concepts": []interface{}{"bar"}, 498 "force": float64(0.7), 499 }, 500 }), 501 }, 502 } 503 vectorSearcher.results = []search.Result{ 504 { 505 ClassName: "BestClass", 506 ID: "123-456-789", 507 Certainty: 0.5, 508 Dist: 0.5, 509 Dims: 128, 510 }, 511 { 512 ClassName: "AnAction", 513 ID: "987-654-321", 514 Certainty: 0.5, 515 Dist: 0.5, 516 Dims: 128, 517 }, 518 } 519 520 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearCustomText", 128) 521 res, err := traverser.Explore(context.Background(), nil, params) 522 require.Nil(t, err) 523 assert.Equal(t, []search.Result{ 524 { 525 ClassName: "BestClass", 526 ID: "123-456-789", 527 Beacon: "weaviate://localhost/BestClass/123-456-789", 528 Certainty: 0.5, 529 Dist: 0.5, 530 Dims: 128, 531 }, 532 { 533 ClassName: "AnAction", 534 ID: "987-654-321", 535 Beacon: "weaviate://localhost/AnAction/987-654-321", 536 Certainty: 0.5, 537 Dist: 0.5, 538 Dims: 128, 539 }, 540 }, res) 541 542 // see dummy implementation of MoveTo and MoveAway for why the vector should 543 // be the way it is 544 assert.Equal(t, []float32{1.5, 2.5, 3.5}, vectorSearcher.calledWithVector) 545 assert.Equal(t, 100, vectorSearcher.calledWithLimit, 546 "limit explicitly set") 547 }) 548 549 t.Run("near text with movements and objects set", func(t *testing.T) { 550 authorizer := &fakeAuthorizer{} 551 locks := &fakeLocks{} 552 logger, _ := test.NewNullLogger() 553 vectorSearcher := &fakeVectorSearcher{} 554 log, _ := test.NewNullLogger() 555 metrics := &fakeMetrics{} 556 explorer := NewExplorer(vectorSearcher, log, getFakeModulesProvider(), metrics, defaultConfig) 557 schemaGetter := &fakeSchemaGetter{} 558 traverser := NewTraverser(&config.WeaviateConfig{}, locks, logger, authorizer, 559 vectorSearcher, explorer, schemaGetter, getFakeModulesProvider(), nil, -1) 560 561 params := ExploreParams{ 562 Limit: 100, 563 ModuleParams: map[string]interface{}{ 564 "nearCustomText": extractNearCustomTextParam(map[string]interface{}{ 565 "concepts": []interface{}{"a search term", "another"}, 566 "moveTo": map[string]interface{}{ 567 "concepts": []interface{}{"foo"}, 568 "force": float64(0.7), 569 "objects": []interface{}{ 570 map[string]interface{}{ 571 "id": "e9c12c22-766f-4bde-b140-d4cf8fd6e041", 572 }, 573 }, 574 }, 575 "moveAwayFrom": map[string]interface{}{ 576 "concepts": []interface{}{"bar"}, 577 "force": float64(0.7), 578 "objects": []interface{}{ 579 map[string]interface{}{ 580 "id": "e9c12c22-766f-4bde-b140-d4cf8fd6e042", 581 }, 582 map[string]interface{}{ 583 "beacon": "weaviate://localhost/e9c12c22-766f-4bde-b140-d4cf8fd6e043", 584 }, 585 map[string]interface{}{ 586 "beacon": "weaviate://localhost/e9c12c22-766f-4bde-b140-d4cf8fd6e044", 587 }, 588 }, 589 }, 590 }), 591 }, 592 } 593 vectorSearcher.results = []search.Result{ 594 { 595 ClassName: "BestClass", 596 ID: "123-456-789", 597 Certainty: 0.5, 598 Dist: 0.5, 599 Dims: 128, 600 }, 601 { 602 ClassName: "AnAction", 603 ID: "987-654-321", 604 Certainty: 0.5, 605 Dist: 0.5, 606 Dims: 128, 607 }, 608 } 609 searchRes1 := search.Result{ 610 ClassName: "BestClass", 611 ID: "e9c12c22-766f-4bde-b140-d4cf8fd6e041", 612 Dims: 128, 613 } 614 searchRes2 := search.Result{ 615 ClassName: "BestClass", 616 ID: "e9c12c22-766f-4bde-b140-d4cf8fd6e042", 617 Dims: 128, 618 } 619 searchRes3 := search.Result{ 620 ClassName: "BestClass", 621 ID: "e9c12c22-766f-4bde-b140-d4cf8fd6e043", 622 Dims: 128, 623 } 624 searchRes4 := search.Result{ 625 ClassName: "BestClass", 626 ID: "e9c12c22-766f-4bde-b140-d4cf8fd6e044", 627 Dims: 128, 628 } 629 630 vectorSearcher. 631 On("ObjectByID", strfmt.UUID("e9c12c22-766f-4bde-b140-d4cf8fd6e041")). 632 Return(&searchRes1, nil) 633 vectorSearcher. 634 On("ObjectByID", strfmt.UUID("e9c12c22-766f-4bde-b140-d4cf8fd6e042")). 635 Return(&searchRes2, nil) 636 vectorSearcher. 637 On("ObjectByID", strfmt.UUID("e9c12c22-766f-4bde-b140-d4cf8fd6e043")). 638 Return(&searchRes3, nil) 639 vectorSearcher. 640 On("ObjectByID", strfmt.UUID("e9c12c22-766f-4bde-b140-d4cf8fd6e044")). 641 Return(&searchRes4, nil) 642 643 metrics.On("AddUsageDimensions", "n/a", "explore_graphql", "nearCustomText", 128) 644 res, err := traverser.Explore(context.Background(), nil, params) 645 require.Nil(t, err) 646 assert.Equal(t, []search.Result{ 647 { 648 ClassName: "BestClass", 649 ID: "123-456-789", 650 Beacon: "weaviate://localhost/BestClass/123-456-789", 651 Certainty: 0.5, 652 Dist: 0.5, 653 Dims: 128, 654 }, 655 { 656 ClassName: "AnAction", 657 ID: "987-654-321", 658 Beacon: "weaviate://localhost/AnAction/987-654-321", 659 Certainty: 0.5, 660 Dist: 0.5, 661 Dims: 128, 662 }, 663 }, res) 664 665 // see dummy implementation of MoveTo and MoveAway for why the vector should 666 // be the way it is 667 assert.Equal(t, []float32{1.5, 2.5, 3.5}, vectorSearcher.calledWithVector) 668 assert.Equal(t, 100, vectorSearcher.calledWithLimit, 669 "limit explicitly set") 670 }) 671 }