From f2bbeb3500ec212f43bcf2e4a6e64ec529ca3472 Mon Sep 17 00:00:00 2001 From: Toby Evans Date: Tue, 21 Nov 2023 15:32:19 -0600 Subject: [PATCH] [10.x] Add search engine meta data to results (#780) * Add meilisearch meta data to results add result meta data to the return models with `withScoutMetadata` * Update src/Engines/MeilisearchEngine.php * add engine metadata to AlgoliaEngine * move adding model meta data to after filtering * Add assertions to test scoutMetadata value for both Aloglia and Meilisearch engines * Add metadata to lazyMap() for both engines as well * codestyle fixes --------- Co-authored-by: Dries Vints --- src/Engines/AlgoliaEngine.php | 20 ++++++++++++++++++++ src/Engines/MeilisearchEngine.php | 20 ++++++++++++++++++++ tests/Fixtures/SearchableModel.php | 7 +------ tests/Unit/AlgoliaEngineTest.php | 20 ++++++++++++++------ tests/Unit/MeilisearchEngineTest.php | 19 ++++++++++++++----- 5 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/Engines/AlgoliaEngine.php b/src/Engines/AlgoliaEngine.php index c81c9b2e..cc2a3b8a 100644 --- a/src/Engines/AlgoliaEngine.php +++ b/src/Engines/AlgoliaEngine.php @@ -210,6 +210,16 @@ public function map(Builder $builder, $results, $model) $builder, $objectIds )->filter(function ($model) use ($objectIds) { return in_array($model->getScoutKey(), $objectIds); + })->map(function ($model) use ($results, $objectIdPositions) { + $result = $results['hits'][$objectIdPositions[$model->getScoutKey()]] ?? []; + + foreach ($result as $key => $value) { + if (substr($key, 0, 1) === '_') { + $model->withScoutMetadata($key, $value); + } + } + + return $model; })->sortBy(function ($model) use ($objectIdPositions) { return $objectIdPositions[$model->getScoutKey()]; })->values(); @@ -236,6 +246,16 @@ public function lazyMap(Builder $builder, $results, $model) $builder, $objectIds )->cursor()->filter(function ($model) use ($objectIds) { return in_array($model->getScoutKey(), $objectIds); + })->map(function ($model) use ($results, $objectIdPositions) { + $result = $results['hits'][$objectIdPositions[$model->getScoutKey()]] ?? []; + + foreach ($result as $key => $value) { + if (substr($key, 0, 1) === '_') { + $model->withScoutMetadata($key, $value); + } + } + + return $model; })->sortBy(function ($model) use ($objectIdPositions) { return $objectIdPositions[$model->getScoutKey()]; })->values(); diff --git a/src/Engines/MeilisearchEngine.php b/src/Engines/MeilisearchEngine.php index eb8f4d28..3e5f02b7 100644 --- a/src/Engines/MeilisearchEngine.php +++ b/src/Engines/MeilisearchEngine.php @@ -293,6 +293,16 @@ public function map(Builder $builder, $results, $model) $builder, $objectIds )->filter(function ($model) use ($objectIds) { return in_array($model->getScoutKey(), $objectIds); + })->map(function ($model) use ($results, $objectIdPositions) { + $result = $results['hits'][$objectIdPositions[$model->getScoutKey()]] ?? []; + + foreach ($result as $key => $value) { + if (substr($key, 0, 1) === '_') { + $model->withScoutMetadata($key, $value); + } + } + + return $model; })->sortBy(function ($model) use ($objectIdPositions) { return $objectIdPositions[$model->getScoutKey()]; })->values(); @@ -319,6 +329,16 @@ public function lazyMap(Builder $builder, $results, $model) $builder, $objectIds )->cursor()->filter(function ($model) use ($objectIds) { return in_array($model->getScoutKey(), $objectIds); + })->map(function ($model) use ($results, $objectIdPositions) { + $result = $results['hits'][$objectIdPositions[$model->getScoutKey()]] ?? []; + + foreach ($result as $key => $value) { + if (substr($key, 0, 1) === '_') { + $model->withScoutMetadata($key, $value); + } + } + + return $model; })->sortBy(function ($model) use ($objectIdPositions) { return $objectIdPositions[$model->getScoutKey()]; })->values(); diff --git a/tests/Fixtures/SearchableModel.php b/tests/Fixtures/SearchableModel.php index d6268323..d03c3aca 100644 --- a/tests/Fixtures/SearchableModel.php +++ b/tests/Fixtures/SearchableModel.php @@ -14,15 +14,10 @@ class SearchableModel extends Model * * @var array */ - protected $fillable = ['id']; + protected $fillable = ['id', 'name']; public function searchableAs() { return 'table'; } - - public function scoutMetadata() - { - return []; - } } diff --git a/tests/Unit/AlgoliaEngineTest.php b/tests/Unit/AlgoliaEngineTest.php index 7346f3c7..98c991b1 100644 --- a/tests/Unit/AlgoliaEngineTest.php +++ b/tests/Unit/AlgoliaEngineTest.php @@ -156,17 +156,23 @@ public function test_map_correctly_maps_results_to_models() $engine = new AlgoliaEngine($client); $model = m::mock(stdClass::class); + $model->shouldReceive('getScoutModelsByIds')->andReturn($models = Collection::make([ - new SearchableModel(['id' => 1]), + new SearchableModel(['id' => 1, 'name' => 'test']), ])); $builder = m::mock(Builder::class); - $results = $engine->map($builder, ['nbHits' => 1, 'hits' => [ - ['objectID' => 1, 'id' => 1], - ]], $model); + $results = $engine->map($builder, [ + 'nbHits' => 1, + 'hits' => [ + ['objectID' => 1, 'id' => 1, '_rankingInfo' => ['nbTypos' => 0]], + ], + ], $model); $this->assertCount(1, $results); + $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals(['_rankingInfo' => ['nbTypos' => 0]], $results->first()->scoutMetaData()); } public function test_map_method_respects_order() @@ -210,16 +216,18 @@ public function test_lazy_map_correctly_maps_results_to_models() $model = m::mock(stdClass::class); $model->shouldReceive('queryScoutModelsByIds->cursor')->andReturn($models = LazyCollection::make([ - new SearchableModel(['id' => 1]), + new SearchableModel(['id' => 1, 'name' => 'test']), ])); $builder = m::mock(Builder::class); $results = $engine->lazyMap($builder, ['nbHits' => 1, 'hits' => [ - ['objectID' => 1, 'id' => 1], + ['objectID' => 1, 'id' => 1, '_rankingInfo' => ['nbTypos' => 0]], ]], $model); $this->assertCount(1, $results); + $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals(['_rankingInfo' => ['nbTypos' => 0]], $results->first()->scoutMetaData()); } public function test_lazy_map_method_respects_order() diff --git a/tests/Unit/MeilisearchEngineTest.php b/tests/Unit/MeilisearchEngineTest.php index 87887417..ff57c7f9 100644 --- a/tests/Unit/MeilisearchEngineTest.php +++ b/tests/Unit/MeilisearchEngineTest.php @@ -286,17 +286,22 @@ public function test_map_correctly_maps_results_to_models() $model = m::mock(stdClass::class); $model->shouldReceive(['getScoutKeyName' => 'id']); - $model->shouldReceive('getScoutModelsByIds')->andReturn($models = Collection::make([new SearchableModel(['id' => 1])])); + $model->shouldReceive('getScoutModelsByIds')->andReturn($models = Collection::make([ + new SearchableModel(['id' => 1, 'name' => 'test']), + ])); + $builder = m::mock(Builder::class); $results = $engine->map($builder, [ 'totalHits' => 1, 'hits' => [ - ['id' => 1], + ['id' => 1, '_rankingScore' => 0.86], ], ], $model); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); + $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals(['_rankingScore' => 0.86], $results->first()->scoutMetadata()); } public function test_map_method_respects_order() @@ -341,17 +346,21 @@ public function test_lazy_map_correctly_maps_results_to_models() $model = m::mock(stdClass::class); $model->shouldReceive(['getScoutKeyName' => 'id']); - $model->shouldReceive('queryScoutModelsByIds->cursor')->andReturn($models = LazyCollection::make([new SearchableModel(['id' => 1])])); + $model->shouldReceive('queryScoutModelsByIds->cursor')->andReturn($models = LazyCollection::make([ + new SearchableModel(['id' => 1, 'name' => 'test']), + ])); $builder = m::mock(Builder::class); $results = $engine->lazyMap($builder, [ 'totalHits' => 1, 'hits' => [ - ['id' => 1], + ['id' => 1, '_rankingScore' => 0.86], ], ], $model); $this->assertEquals(1, count($results)); + $this->assertEquals(['id' => 1, 'name' => 'test'], $results->first()->toArray()); + $this->assertEquals(['_rankingScore' => 0.86], $results->first()->scoutMetadata()); } public function test_lazy_map_method_respects_order()