From 7c4fd186a8e063f4f3c03012ee0bdb29c1c2b729 Mon Sep 17 00:00:00 2001 From: Armin Winkler Date: Tue, 24 Sep 2024 13:44:45 +0200 Subject: [PATCH 1/7] fix: missing scout metadata for typesense search --- src/Engines/TypesenseEngine.php | 13 ++++++++++ tests/Unit/TypesenseEngineTest.php | 40 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/Engines/TypesenseEngine.php b/src/Engines/TypesenseEngine.php index 18146989..d191243a 100644 --- a/src/Engines/TypesenseEngine.php +++ b/src/Engines/TypesenseEngine.php @@ -392,6 +392,19 @@ public function map(Builder $builder, $results, $model) ->filter(static function ($model) use ($objectIds) { return in_array($model->getScoutKey(), $objectIds, false); }) + ->map(static function ($model) use ($hits, $objectIdPositions) { + $result = $hits[$objectIdPositions[$model->getScoutKey()]] ?? []; + + foreach ($result as $key => $value) { + if ($key === 'document') { + continue; + } + + $model->withScoutMetadata($key, $value); + } + + return $model; + }) ->sortBy(static function ($model) use ($objectIdPositions) { return $objectIdPositions[$model->getScoutKey()]; }) diff --git a/tests/Unit/TypesenseEngineTest.php b/tests/Unit/TypesenseEngineTest.php index 9f360a9b..18b5bd8f 100644 --- a/tests/Unit/TypesenseEngineTest.php +++ b/tests/Unit/TypesenseEngineTest.php @@ -183,6 +183,46 @@ public function test_map_ids_method(): void $this->assertEquals([1, 2, 3], $mappedIds->toArray()); } + public function test_map_correctly_maps_results_to_models() + { + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + + $model = m::mock(stdClass::class); + $model->shouldReceive(['getScoutKeyName' => 'id']); + $model->shouldReceive('getScoutModelsByIds')->andReturn(Collection::make([ + new SearchableModel([ + 'document' => [ + [ + 'id' => 1, + 'name' => 'test', + ] + ], + 'geo_distance_meters' => ['location' => 5], + 'highlights' => [], + ]), + ])); + + $builder = m::mock(Builder::class); + + $results = $engine->map($builder, [ + 'found' => 1, + 'hits' => [ + [ + 'document' => ['id' => 1, 'name' => 'test'], + 'geo_distance_meters' => ['location' => 5], + 'highlights' => [], + ], + ], + ], $model); + + $this->assertCount(1, $results); + $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals( + ['geo_distance_meters' => ['location' => 5], 'highlights' => []], + $results->first()->scoutMetadata() + ); + } + public function test_get_total_count_method(): void { // Sample search results with 'found' key From 27191c8382406e6525d6d71fcbba09ce42e619f1 Mon Sep 17 00:00:00 2001 From: Armin Winkler Date: Tue, 24 Sep 2024 13:53:11 +0200 Subject: [PATCH 2/7] Revert "fix: missing scout metadata for typesense search" --- src/Engines/TypesenseEngine.php | 13 ---------- tests/Unit/TypesenseEngineTest.php | 40 ------------------------------ 2 files changed, 53 deletions(-) diff --git a/src/Engines/TypesenseEngine.php b/src/Engines/TypesenseEngine.php index d191243a..18146989 100644 --- a/src/Engines/TypesenseEngine.php +++ b/src/Engines/TypesenseEngine.php @@ -392,19 +392,6 @@ public function map(Builder $builder, $results, $model) ->filter(static function ($model) use ($objectIds) { return in_array($model->getScoutKey(), $objectIds, false); }) - ->map(static function ($model) use ($hits, $objectIdPositions) { - $result = $hits[$objectIdPositions[$model->getScoutKey()]] ?? []; - - foreach ($result as $key => $value) { - if ($key === 'document') { - continue; - } - - $model->withScoutMetadata($key, $value); - } - - return $model; - }) ->sortBy(static function ($model) use ($objectIdPositions) { return $objectIdPositions[$model->getScoutKey()]; }) diff --git a/tests/Unit/TypesenseEngineTest.php b/tests/Unit/TypesenseEngineTest.php index 18b5bd8f..9f360a9b 100644 --- a/tests/Unit/TypesenseEngineTest.php +++ b/tests/Unit/TypesenseEngineTest.php @@ -183,46 +183,6 @@ public function test_map_ids_method(): void $this->assertEquals([1, 2, 3], $mappedIds->toArray()); } - public function test_map_correctly_maps_results_to_models() - { - $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); - - $model = m::mock(stdClass::class); - $model->shouldReceive(['getScoutKeyName' => 'id']); - $model->shouldReceive('getScoutModelsByIds')->andReturn(Collection::make([ - new SearchableModel([ - 'document' => [ - [ - 'id' => 1, - 'name' => 'test', - ] - ], - 'geo_distance_meters' => ['location' => 5], - 'highlights' => [], - ]), - ])); - - $builder = m::mock(Builder::class); - - $results = $engine->map($builder, [ - 'found' => 1, - 'hits' => [ - [ - 'document' => ['id' => 1, 'name' => 'test'], - 'geo_distance_meters' => ['location' => 5], - 'highlights' => [], - ], - ], - ], $model); - - $this->assertCount(1, $results); - $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); - $this->assertEquals( - ['geo_distance_meters' => ['location' => 5], 'highlights' => []], - $results->first()->scoutMetadata() - ); - } - public function test_get_total_count_method(): void { // Sample search results with 'found' key From 8e70c54bbae5b337886860df66b0ecdeae9d0041 Mon Sep 17 00:00:00 2001 From: Armin Winkler Date: Tue, 24 Sep 2024 14:21:17 +0200 Subject: [PATCH 3/7] fix: missing scout metadata for typesense search --- src/Engines/TypesenseEngine.php | 13 +++++++++++ tests/Unit/TypesenseEngineTest.php | 36 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/Engines/TypesenseEngine.php b/src/Engines/TypesenseEngine.php index 18146989..d191243a 100644 --- a/src/Engines/TypesenseEngine.php +++ b/src/Engines/TypesenseEngine.php @@ -392,6 +392,19 @@ public function map(Builder $builder, $results, $model) ->filter(static function ($model) use ($objectIds) { return in_array($model->getScoutKey(), $objectIds, false); }) + ->map(static function ($model) use ($hits, $objectIdPositions) { + $result = $hits[$objectIdPositions[$model->getScoutKey()]] ?? []; + + foreach ($result as $key => $value) { + if ($key === 'document') { + continue; + } + + $model->withScoutMetadata($key, $value); + } + + return $model; + }) ->sortBy(static function ($model) use ($objectIdPositions) { return $objectIdPositions[$model->getScoutKey()]; }) diff --git a/tests/Unit/TypesenseEngineTest.php b/tests/Unit/TypesenseEngineTest.php index 9f360a9b..57c264fc 100644 --- a/tests/Unit/TypesenseEngineTest.php +++ b/tests/Unit/TypesenseEngineTest.php @@ -183,6 +183,42 @@ public function test_map_ids_method(): void $this->assertEquals([1, 2, 3], $mappedIds->toArray()); } + public function test_map_correctly_maps_results_to_models() + { + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + + $model = m::mock(stdClass::class); + $model->shouldReceive(['getScoutKeyName' => 'id']); + $model->shouldReceive('getScoutModelsByIds')->andReturn( + Collection::make([ + new SearchableModel([ + 'id' => 1, + 'name' => 'test', + ]), + ]) + ); + + $builder = m::mock(Builder::class); + + $results = $engine->map($builder, [ + 'found' => 1, + 'hits' => [ + [ + 'document' => ['id' => 1, 'name' => 'test'], + 'geo_distance_meters' => ['location' => 5], + 'highlights' => [], + ], + ], + ], $model); + + $this->assertCount(1, $results); + $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals( + ['geo_distance_meters' => ['location' => 5], 'highlights' => []], + $results->first()->scoutMetadata() + ); + } + public function test_get_total_count_method(): void { // Sample search results with 'found' key From 558ff31ead9543ce47518ccf65723bc096b2037b Mon Sep 17 00:00:00 2001 From: Armin Winkler Date: Thu, 3 Oct 2024 22:08:58 +0200 Subject: [PATCH 4/7] fix: add more unittest for mapping scout metadata --- tests/Unit/TypesenseEngineTest.php | 116 ++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 4 deletions(-) diff --git a/tests/Unit/TypesenseEngineTest.php b/tests/Unit/TypesenseEngineTest.php index 57c264fc..e09f877d 100644 --- a/tests/Unit/TypesenseEngineTest.php +++ b/tests/Unit/TypesenseEngineTest.php @@ -191,10 +191,7 @@ public function test_map_correctly_maps_results_to_models() $model->shouldReceive(['getScoutKeyName' => 'id']); $model->shouldReceive('getScoutModelsByIds')->andReturn( Collection::make([ - new SearchableModel([ - 'id' => 1, - 'name' => 'test', - ]), + new SearchableModel(['id' => 1, 'name' => 'test']), ]) ); @@ -219,6 +216,117 @@ public function test_map_correctly_maps_results_to_models() ); } + public function test_map_correctly_maps_results_to_models_with_multiple_hits() + { + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + + $model = m::mock(stdClass::class); + $model->shouldReceive(['getScoutKeyName' => 'id']); + $model->shouldReceive('getScoutModelsByIds')->andReturn( + Collection::make([ + new SearchableModel(['id' => 1, 'name' => 'test1']), + new SearchableModel(['id' => 4, 'name' => 'test4']), + new SearchableModel(['id' => 6, 'name' => 'test6']), + ]) + ); + + $builder = m::mock(Builder::class); + + $results = $engine->map($builder, [ + 'found' => 3, + 'hits' => [ + [ + 'document' => ['id' => 1, 'name' => 'test1'], + 'geo_distance_meters' => ['location' => 1], + 'highlights' => [1], + ], + [ + 'document' => ['id' => 6, 'name' => 'test6'], + 'geo_distance_meters' => ['location' => 6], + 'highlights' => [6], + ], + [ + 'document' => ['id' => 4, 'name' => 'test4'], + 'geo_distance_meters' => ['location' => 4], + 'highlights' => [4], + ], + ], + ], $model); + + $this->assertCount(3, $results); + $this->assertEquals(['id' => 6, 'name' => 'test6'], $results[1]->toArray()); + + foreach ($results as $result) { + $this->assertNotEmpty($result->scoutMetadata()); + + $this->assertEquals( + ['geo_distance_meters' => ['location' => $result->id], 'highlights' => [$result->id]], + $result->scoutMetadata() + ); + } + } + + public function test_scoutMetadata_is_empty_for_missing_hits() + { + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + + $model = m::mock(stdClass::class); + $model->shouldReceive(['getScoutKeyName' => 'id']); + $model->shouldReceive('getScoutModelsByIds')->andReturn( + Collection::make([ + new SearchableModel(['id' => null, 'name' => 'test']), + ]) + ); + + $builder = m::mock(Builder::class); + + $results = $engine->map($builder, [ + 'found' => 1, + 'grouped_hits' => [ + 'hits' => [ + [ + 'document' => ['id' => 1, 'name' => 'test'], + 'geo_distance_meters' => ['location' => 5], + 'highlights' => [], + ], + ], + ], + ], $model); + + $this->assertCount(1, $results); + $this->assertEquals(['id' => null, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals([], $results->first()->scoutMetadata()); + } + + public function test_that_document_result_is_not_added_to_scoutMetadata() + { + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + + $model = m::mock(stdClass::class); + $model->shouldReceive(['getScoutKeyName' => 'id']); + $model->shouldReceive('getScoutModelsByIds')->andReturn( + Collection::make([ + new SearchableModel(['id' => 1, 'name' => 'test']), + ]) + ); + + $builder = m::mock(Builder::class); + + $results = $engine->map($builder, [ + 'found' => 1, + 'hits' => [ + [ + 'document' => ['id' => 1, 'name' => 'test'], + 'highlights' => [], + ], + ], + ], $model); + + $this->assertCount(1, $results); + $this->assertArrayNotHasKey('document', $results->first()->scoutMetadata()); + $this->assertArrayHasKey('highlights', $results->first()->scoutMetadata()); + } + public function test_get_total_count_method(): void { // Sample search results with 'found' key From bcbc77347fa8e49b70b1f195b0f6d55300773c5a Mon Sep 17 00:00:00 2001 From: Armin Winkler Date: Thu, 3 Oct 2024 22:19:54 +0200 Subject: [PATCH 5/7] fix: add more unittest for mapping scout metadata --- tests/Unit/TypesenseEngineTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Unit/TypesenseEngineTest.php b/tests/Unit/TypesenseEngineTest.php index 8fcc30a9..0e049430 100644 --- a/tests/Unit/TypesenseEngineTest.php +++ b/tests/Unit/TypesenseEngineTest.php @@ -185,7 +185,7 @@ public function test_map_ids_method(): void public function test_map_correctly_maps_results_to_models() { - $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class), 10); $model = m::mock(stdClass::class); $model->shouldReceive(['getScoutKeyName' => 'id']); @@ -218,7 +218,7 @@ public function test_map_correctly_maps_results_to_models() public function test_map_correctly_maps_results_to_models_with_multiple_hits() { - $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class), 10); $model = m::mock(stdClass::class); $model->shouldReceive(['getScoutKeyName' => 'id']); @@ -268,7 +268,7 @@ public function test_map_correctly_maps_results_to_models_with_multiple_hits() public function test_scoutMetadata_is_empty_for_missing_hits() { - $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class), 10); $model = m::mock(stdClass::class); $model->shouldReceive(['getScoutKeyName' => 'id']); @@ -300,7 +300,7 @@ public function test_scoutMetadata_is_empty_for_missing_hits() public function test_that_document_result_is_not_added_to_scoutMetadata() { - $engine = new TypesenseEngine($this->createMock(TypesenseClient::class)); + $engine = new TypesenseEngine($this->createMock(TypesenseClient::class), 10); $model = m::mock(stdClass::class); $model->shouldReceive(['getScoutKeyName' => 'id']); From c8a7bb8647811555a4a6b7ba4783929ed9184979 Mon Sep 17 00:00:00 2001 From: Armin Winkler Date: Thu, 3 Oct 2024 22:23:40 +0200 Subject: [PATCH 6/7] fix: add more unittest for mapping scout metadata --- tests/Unit/TypesenseEngineTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/TypesenseEngineTest.php b/tests/Unit/TypesenseEngineTest.php index 0e049430..4e3313c0 100644 --- a/tests/Unit/TypesenseEngineTest.php +++ b/tests/Unit/TypesenseEngineTest.php @@ -274,7 +274,7 @@ public function test_scoutMetadata_is_empty_for_missing_hits() $model->shouldReceive(['getScoutKeyName' => 'id']); $model->shouldReceive('getScoutModelsByIds')->andReturn( Collection::make([ - new SearchableModel(['id' => null, 'name' => 'test']), + new SearchableModel(['id' => '', 'name' => 'test']), ]) ); From 5fd05e0ca8c0aaa6b25fae49738664ad1e38e3cd Mon Sep 17 00:00:00 2001 From: Armin Winkler Date: Thu, 3 Oct 2024 22:44:12 +0200 Subject: [PATCH 7/7] fix: add more unittest for mapping scout metadata --- tests/Unit/TypesenseEngineTest.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/Unit/TypesenseEngineTest.php b/tests/Unit/TypesenseEngineTest.php index 4e3313c0..72262d60 100644 --- a/tests/Unit/TypesenseEngineTest.php +++ b/tests/Unit/TypesenseEngineTest.php @@ -274,7 +274,7 @@ public function test_scoutMetadata_is_empty_for_missing_hits() $model->shouldReceive(['getScoutKeyName' => 'id']); $model->shouldReceive('getScoutModelsByIds')->andReturn( Collection::make([ - new SearchableModel(['id' => '', 'name' => 'test']), + new SearchableModel(['id' => 1, 'name' => 'test']), ]) ); @@ -283,18 +283,20 @@ public function test_scoutMetadata_is_empty_for_missing_hits() $results = $engine->map($builder, [ 'found' => 1, 'grouped_hits' => [ - 'hits' => [ - [ - 'document' => ['id' => 1, 'name' => 'test'], - 'geo_distance_meters' => ['location' => 5], - 'highlights' => [], + 1 => [ + 'hits' => [ + [ + 'document' => ['id' => 1, 'name' => 'test'], + 'geo_distance_meters' => ['location' => 5], + 'highlights' => [], + ], ], ], ], ], $model); $this->assertCount(1, $results); - $this->assertEquals(['id' => null, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); $this->assertEquals([], $results->first()->scoutMetadata()); }