Skip to content

Commit

Permalink
Support laravel/scout v9 (#34)
Browse files Browse the repository at this point in the history
* Update variable names and return types

* Support laravel/scout:^9.0

* Add tests for cursor() and fix implementation
  • Loading branch information
Namoshek authored May 15, 2021
1 parent 57cb0a6 commit 4c4107d
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 14 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"illuminate/contracts": "^6.0|^7.0|^8.0",
"illuminate/database": "^6.0|^7.0|^8.0",
"illuminate/support": "^6.0|^7.0|^8.0",
"laravel/scout": "^7.0|^8.0",
"laravel/scout": "^7.0|^8.0|^9.0",
"staudenmeir/laravel-cte": "^1.0",
"wamania/php-stemmer": "^2.0"
},
Expand Down
77 changes: 66 additions & 11 deletions src/DatabaseEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Laravel\Scout\Builder;
use Laravel\Scout\Engines\Engine;
use Laravel\Scout\Searchable;
Expand Down Expand Up @@ -89,36 +90,36 @@ public function search(Builder $builder): SearchResult
* @param Builder $builder
* @param int $perPage
* @param int $page
* @return mixed
* @return SearchResult
*/
public function paginate(Builder $builder, $perPage, $page)
public function paginate(Builder $builder, $perPage, $page): SearchResult
{
return $this->seeker->search($builder, $page, $perPage);
}

/**
* Pluck and return the primary keys of the given results.
*
* @param SearchResult $result
* @param SearchResult $results
* @return Collection
*/
public function mapIds($result): Collection
public function mapIds($results): Collection
{
return collect($result->getIdentifiers());
return collect($results->getIdentifiers());
}

/**
* Map the given results to instances of the given model.
*
* @param Builder $builder
* @param SearchResult $result
* @param SearchResult $results
* @param Model|Searchable $model
* @return EloquentCollection
* @throws \InvalidArgumentException
*/
public function map(Builder $builder, $result, $model): EloquentCollection
public function map(Builder $builder, $results, $model): EloquentCollection
{
$objectIds = $result->getIdentifiers();
$objectIds = $results->getIdentifiers();

if (count($objectIds) === 0) {
return EloquentCollection::make();
Expand All @@ -136,14 +137,68 @@ public function map(Builder $builder, $result, $model): EloquentCollection
->values();
}

/**
* Map the given results to instances of the given model via a lazy collection.
*
* @param Builder $builder
* @param mixed $results
* @param Model|Searchable $model
* @return LazyCollection
*/
public function lazyMap(Builder $builder, $results, $model): LazyCollection
{
$objectIds = $results->getIdentifiers();

if (count($objectIds) === 0) {
return LazyCollection::empty();
}

$objectIdPositions = array_flip($objectIds);

return $model->queryScoutModelsByIds($builder, $objectIds)
->cursor()
->filter(function ($model) use ($objectIds) {
return in_array($model->getScoutKey(), $objectIds);
})
->sortBy(function ($model) use ($objectIdPositions) {
return $objectIdPositions[$model->getScoutKey()];
})
->values();
}

/**
* Get the total count from a raw result returned by the engine.
*
* @param SearchResult $result
* @param SearchResult $results
* @return int
*/
public function getTotalCount($result): int
public function getTotalCount($results): int
{
return $results->getHits();
}

/**
* Create a search index.
*
* @param string $name
* @param array $options
* @return void
* @throws ScoutDatabaseException
*/
public function createIndex($name, array $options = []): void
{
throw new ScoutDatabaseException('Scout Database indexes are created automatically upon adding objects (index table must exist).');
}

/**
* Delete a search index.
*
* @param string $name
* @return void
* @throws ScoutDatabaseException
*/
public function deleteIndex($name): void
{
return $result->getHits();
$this->indexer->deleteIndex($name);
}
}
16 changes: 14 additions & 2 deletions src/DatabaseIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,23 @@ public function deleteFromIndex(Collection $models): void
* @throws ScoutDatabaseException
*/
public function deleteEntireModelFromIndex(Model $model): void
{
$this->deleteIndex($model->searchableAs());
}

/**
* Removes all indexed data from the index with the given name.
*
* @param string $name
* @return void
* @throws ScoutDatabaseException
*/
public function deleteIndex(string $name): void
{
try {
// Delete the affected documents from the documents table.
// Delete the affected documents from the documents table. The document type is the index name.
$this->connection->table($this->databaseHelper->indexTable())
->where('document_type', $model->searchableAs())
->where('document_type', $name)
->delete();
} catch (\Throwable $e) {
throw new ScoutDatabaseException('Deleting all entries of type from search index failed.', 0, $e);
Expand Down
18 changes: 18 additions & 0 deletions tests/DatabaseSeekerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ public function test_finds_documents_of_searched_type_which_have_term_with_exact
$this->assertEquals('Max Mustermann', $result->shift()->name);
}

public function test_finds_documents_of_searched_type_which_have_term_with_exact_match_2(): void
{
$result = User::search('abc')->cursor();

$this->assertSame(2, $result->count());
$this->assertEquals([2, 1], $result->pluck('id')->toArray());
$this->assertEquals('Mia Musterfrau', $result->skip(0)->first()->name);
$this->assertEquals('Max Mustermann', $result->skip(1)->first()->name);
}

public function test_finds_no_documents_of_searched_type_if_no_match_is_given(): void
{
$result = User::search('randomness')->get();
Expand All @@ -106,6 +116,14 @@ public function test_finds_no_documents_of_searched_type_if_no_match_is_given():
$this->assertEquals([], $result->toArray());
}

public function test_finds_no_documents_of_searched_type_if_no_match_is_given_2(): void
{
$result = User::search('randomness')->cursor();

$this->assertSame(0, $result->count());
$this->assertEquals([], $result->toArray());
}

public function test_finds_first_matching_document(): void
{
$result = User::search('abc')->first();
Expand Down

0 comments on commit 4c4107d

Please sign in to comment.