Skip to content

Commit

Permalink
- Prevent unnecessary api calls on Collection (index). #818 (#820)
Browse files Browse the repository at this point in the history
* - Prevent unnecessary api calls on Collection (index).

* - style fix.

* - Added Typesense searchable test case.
  • Loading branch information
AbdullahFaqeir authored Apr 9, 2024
1 parent cfdcd43 commit 8af517e
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 21 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
"require-dev": {
"algolia/algoliasearch-client-php": "^3.2",
"typesense/typesense-php": "^4.9",
"typesense/typesense-php": "^4.9.2",
"meilisearch/meilisearch-php": "^1.0",
"mockery/mockery": "^1.0",
"orchestra/testbench": "^7.31|^8.11|^9.0",
Expand Down
36 changes: 16 additions & 20 deletions src/Engines/TypesenseEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
use stdClass;
use Typesense\Client as Typesense;
use Typesense\Collection as TypesenseCollection;
use Typesense\Document;
use Typesense\Exceptions\ObjectNotFound;
use Typesense\Exceptions\TypesenseClientError;

class TypesenseEngine extends Engine
Expand Down Expand Up @@ -66,7 +64,7 @@ public function update($models)

$objects = $models->map(function ($model) {
if (empty($searchableData = $model->toSearchableArray())) {
return;
return null;
}

return array_merge(
Expand All @@ -86,7 +84,7 @@ public function update($models)
/**
* Import the given documents into the index.
*
* @param \TypesenseCollection $collectionIndex
* @param TypesenseCollection $collectionIndex
* @param array $documents
* @param string $action
* @return \Illuminate\Support\Collection
Expand Down Expand Up @@ -156,7 +154,7 @@ public function delete($models)
/**
* Delete a document from the index.
*
* @param \TypesenseCollection $collectionIndex
* @param TypesenseCollection $collectionIndex
* @param mixed $modelId
* @return array
*
Expand Down Expand Up @@ -487,7 +485,7 @@ public function deleteIndex($name)
* Get collection from model or create new one.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \TypesenseCollection
* @return TypesenseCollection
*
* @throws \Typesense\Exceptions\TypesenseClientError
* @throws \Http\Client\Exception
Expand All @@ -496,25 +494,23 @@ protected function getOrCreateCollectionFromModel($model): TypesenseCollection
{
$index = $this->typesense->getCollections()->{$model->searchableAs()};

try {
$index->retrieve();

if ($index->exists() === true) {
return $index;
} catch (ObjectNotFound $exception) {
$schema = config('scout.typesense.model-settings.'.get_class($model).'.collection-schema') ?? [];
}

if (method_exists($model, 'typesenseCollectionSchema')) {
$schema = $model->typesenseCollectionSchema();
}
$schema = config('scout.typesense.model-settings.'.get_class($model).'.collection-schema') ?? [];

if (! isset($schema['name'])) {
$schema['name'] = $model->searchableAs();
}

$this->typesense->getCollections()->create($schema);
if (method_exists($model, 'typesenseCollectionSchema')) {
$schema = $model->typesenseCollectionSchema();
}

return $this->typesense->getCollections()->{$model->searchableAs()};
if (! isset($schema['name'])) {
$schema['name'] = $model->searchableAs();
}

$this->typesense->getCollections()->create($schema);

return $this->typesense->getCollections()->{$model->searchableAs()};
}

/**
Expand Down
171 changes: 171 additions & 0 deletions tests/Integration/TypesenseSearchableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php

namespace Laravel\Scout\Tests\Integration;

use Illuminate\Support\Env;
use Laravel\Scout\Tests\Fixtures\User;

/**
* @group typesense
* @group external-network
*/
class TypesenseSearchableTest extends TestCase
{
use SearchableTests;

/**
* Define environment setup.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
protected function defineEnvironment($app)
{
if (is_null(Env::get('TYPESENSE_API_KEY'))) {
$this->markTestSkipped();
}

$this->defineScoutEnvironment($app);
}

/**
* Define database migrations.
*
* @return void
*/
protected function defineDatabaseMigrations()
{
$this->defineScoutDatabaseMigrations();
}

/**
* Perform any work that should take place once the database has finished refreshing.
*
* @return void
*/
protected function afterRefreshingDatabase()
{
$this->importScoutIndexFrom(User::class);
}

public function test_it_can_use_basic_search()
{
$results = $this->itCanUseBasicSearch();

$this->assertSame([
11 => 'Larry Casper',
1 => 'Laravel Framework',
44 => 'Amos Larson Sr.',
43 => 'Dana Larson Sr.',
42 => 'Dax Larkin',
41 => 'Gudrun Larkin',
40 => 'Otis Larson MD',
39 => 'Linkwood Larkin',
20 => 'Prof. Larry Prosacco DVM',
12 => 'Reta Larkin',
], $results->pluck('name', 'id')->all());
}

public function test_it_can_use_basic_search_with_query_callback()
{
$results = $this->itCanUseBasicSearchWithQueryCallback();

$this->assertSame([
1 => 'Laravel Framework',
44 => 'Amos Larson Sr.',
43 => 'Dana Larson Sr.',
42 => 'Dax Larkin',
41 => 'Gudrun Larkin',
40 => 'Otis Larson MD',
12 => 'Reta Larkin',
], $results->pluck('name', 'id')->all());
}

public function test_it_can_use_basic_search_to_fetch_keys()
{
$results = $this->itCanUseBasicSearchToFetchKeys();

$this->assertSame([
'11',
'1',
'44',
'43',
'42',
'41',
'40',
'39',
'20',
'12',
], $results->all());
}

public function test_it_can_use_basic_search_with_query_callback_to_fetch_keys()
{
$results = $this->itCanUseBasicSearchWithQueryCallbackToFetchKeys();

$this->assertSame([
'11',
'1',
'44',
'43',
'42',
'41',
'40',
'39',
'20',
'12',
], $results->all());
}

public function test_it_return_same_keys_with_query_callback()
{
$this->assertSame(
$this->itCanUseBasicSearchToFetchKeys()->all(),
$this->itCanUseBasicSearchWithQueryCallbackToFetchKeys()->all()
);
}

public function test_it_can_use_paginated_search()
{
[$page1, $page2] = $this->itCanUsePaginatedSearch();

$this->assertSame([
11 => 'Larry Casper',
1 => 'Laravel Framework',
44 => 'Amos Larson Sr.',
43 => 'Dana Larson Sr.',
42 => 'Dax Larkin',
], $page1->pluck('name', 'id')->all());

$this->assertSame([
41 => 'Gudrun Larkin',
40 => 'Otis Larson MD',
39 => 'Linkwood Larkin',
20 => 'Prof. Larry Prosacco DVM',
12 => 'Reta Larkin',
], $page2->pluck('name', 'id')->all());
}

public function test_it_can_use_paginated_search_with_query_callback()
{
[$page1, $page2] = $this->itCanUsePaginatedSearchWithQueryCallback();

$this->assertSame([
1 => 'Laravel Framework',
44 => 'Amos Larson Sr.',
43 => 'Dana Larson Sr.',
42 => 'Dax Larkin',
], $page1->pluck('name', 'id')->all());

$this->assertSame([
41 => 'Gudrun Larkin',
40 => 'Otis Larson MD',
12 => 'Reta Larkin',
], $page2->pluck('name', 'id')->all());
}

protected static function scoutDriver(): string
{
return 'typesense';
}
}

0 comments on commit 8af517e

Please sign in to comment.