Skip to content

Commit 8af517e

Browse files
- Prevent unnecessary api calls on Collection (index). #818 (#820)
* - Prevent unnecessary api calls on Collection (index). * - style fix. * - Added Typesense searchable test case.
1 parent cfdcd43 commit 8af517e

File tree

3 files changed

+188
-21
lines changed

3 files changed

+188
-21
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"require-dev": {
2828
"algolia/algoliasearch-client-php": "^3.2",
29-
"typesense/typesense-php": "^4.9",
29+
"typesense/typesense-php": "^4.9.2",
3030
"meilisearch/meilisearch-php": "^1.0",
3131
"mockery/mockery": "^1.0",
3232
"orchestra/testbench": "^7.31|^8.11|^9.0",

src/Engines/TypesenseEngine.php

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
use stdClass;
1212
use Typesense\Client as Typesense;
1313
use Typesense\Collection as TypesenseCollection;
14-
use Typesense\Document;
15-
use Typesense\Exceptions\ObjectNotFound;
1614
use Typesense\Exceptions\TypesenseClientError;
1715

1816
class TypesenseEngine extends Engine
@@ -66,7 +64,7 @@ public function update($models)
6664

6765
$objects = $models->map(function ($model) {
6866
if (empty($searchableData = $model->toSearchableArray())) {
69-
return;
67+
return null;
7068
}
7169

7270
return array_merge(
@@ -86,7 +84,7 @@ public function update($models)
8684
/**
8785
* Import the given documents into the index.
8886
*
89-
* @param \TypesenseCollection $collectionIndex
87+
* @param TypesenseCollection $collectionIndex
9088
* @param array $documents
9189
* @param string $action
9290
* @return \Illuminate\Support\Collection
@@ -156,7 +154,7 @@ public function delete($models)
156154
/**
157155
* Delete a document from the index.
158156
*
159-
* @param \TypesenseCollection $collectionIndex
157+
* @param TypesenseCollection $collectionIndex
160158
* @param mixed $modelId
161159
* @return array
162160
*
@@ -487,7 +485,7 @@ public function deleteIndex($name)
487485
* Get collection from model or create new one.
488486
*
489487
* @param \Illuminate\Database\Eloquent\Model $model
490-
* @return \TypesenseCollection
488+
* @return TypesenseCollection
491489
*
492490
* @throws \Typesense\Exceptions\TypesenseClientError
493491
* @throws \Http\Client\Exception
@@ -496,25 +494,23 @@ protected function getOrCreateCollectionFromModel($model): TypesenseCollection
496494
{
497495
$index = $this->typesense->getCollections()->{$model->searchableAs()};
498496

499-
try {
500-
$index->retrieve();
501-
497+
if ($index->exists() === true) {
502498
return $index;
503-
} catch (ObjectNotFound $exception) {
504-
$schema = config('scout.typesense.model-settings.'.get_class($model).'.collection-schema') ?? [];
499+
}
505500

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

510-
if (! isset($schema['name'])) {
511-
$schema['name'] = $model->searchableAs();
512-
}
513-
514-
$this->typesense->getCollections()->create($schema);
503+
if (method_exists($model, 'typesenseCollectionSchema')) {
504+
$schema = $model->typesenseCollectionSchema();
505+
}
515506

516-
return $this->typesense->getCollections()->{$model->searchableAs()};
507+
if (! isset($schema['name'])) {
508+
$schema['name'] = $model->searchableAs();
517509
}
510+
511+
$this->typesense->getCollections()->create($schema);
512+
513+
return $this->typesense->getCollections()->{$model->searchableAs()};
518514
}
519515

520516
/**
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<?php
2+
3+
namespace Laravel\Scout\Tests\Integration;
4+
5+
use Illuminate\Support\Env;
6+
use Laravel\Scout\Tests\Fixtures\User;
7+
8+
/**
9+
* @group typesense
10+
* @group external-network
11+
*/
12+
class TypesenseSearchableTest extends TestCase
13+
{
14+
use SearchableTests;
15+
16+
/**
17+
* Define environment setup.
18+
*
19+
* @param \Illuminate\Foundation\Application $app
20+
* @return void
21+
*/
22+
protected function defineEnvironment($app)
23+
{
24+
if (is_null(Env::get('TYPESENSE_API_KEY'))) {
25+
$this->markTestSkipped();
26+
}
27+
28+
$this->defineScoutEnvironment($app);
29+
}
30+
31+
/**
32+
* Define database migrations.
33+
*
34+
* @return void
35+
*/
36+
protected function defineDatabaseMigrations()
37+
{
38+
$this->defineScoutDatabaseMigrations();
39+
}
40+
41+
/**
42+
* Perform any work that should take place once the database has finished refreshing.
43+
*
44+
* @return void
45+
*/
46+
protected function afterRefreshingDatabase()
47+
{
48+
$this->importScoutIndexFrom(User::class);
49+
}
50+
51+
public function test_it_can_use_basic_search()
52+
{
53+
$results = $this->itCanUseBasicSearch();
54+
55+
$this->assertSame([
56+
11 => 'Larry Casper',
57+
1 => 'Laravel Framework',
58+
44 => 'Amos Larson Sr.',
59+
43 => 'Dana Larson Sr.',
60+
42 => 'Dax Larkin',
61+
41 => 'Gudrun Larkin',
62+
40 => 'Otis Larson MD',
63+
39 => 'Linkwood Larkin',
64+
20 => 'Prof. Larry Prosacco DVM',
65+
12 => 'Reta Larkin',
66+
], $results->pluck('name', 'id')->all());
67+
}
68+
69+
public function test_it_can_use_basic_search_with_query_callback()
70+
{
71+
$results = $this->itCanUseBasicSearchWithQueryCallback();
72+
73+
$this->assertSame([
74+
1 => 'Laravel Framework',
75+
44 => 'Amos Larson Sr.',
76+
43 => 'Dana Larson Sr.',
77+
42 => 'Dax Larkin',
78+
41 => 'Gudrun Larkin',
79+
40 => 'Otis Larson MD',
80+
12 => 'Reta Larkin',
81+
], $results->pluck('name', 'id')->all());
82+
}
83+
84+
public function test_it_can_use_basic_search_to_fetch_keys()
85+
{
86+
$results = $this->itCanUseBasicSearchToFetchKeys();
87+
88+
$this->assertSame([
89+
'11',
90+
'1',
91+
'44',
92+
'43',
93+
'42',
94+
'41',
95+
'40',
96+
'39',
97+
'20',
98+
'12',
99+
], $results->all());
100+
}
101+
102+
public function test_it_can_use_basic_search_with_query_callback_to_fetch_keys()
103+
{
104+
$results = $this->itCanUseBasicSearchWithQueryCallbackToFetchKeys();
105+
106+
$this->assertSame([
107+
'11',
108+
'1',
109+
'44',
110+
'43',
111+
'42',
112+
'41',
113+
'40',
114+
'39',
115+
'20',
116+
'12',
117+
], $results->all());
118+
}
119+
120+
public function test_it_return_same_keys_with_query_callback()
121+
{
122+
$this->assertSame(
123+
$this->itCanUseBasicSearchToFetchKeys()->all(),
124+
$this->itCanUseBasicSearchWithQueryCallbackToFetchKeys()->all()
125+
);
126+
}
127+
128+
public function test_it_can_use_paginated_search()
129+
{
130+
[$page1, $page2] = $this->itCanUsePaginatedSearch();
131+
132+
$this->assertSame([
133+
11 => 'Larry Casper',
134+
1 => 'Laravel Framework',
135+
44 => 'Amos Larson Sr.',
136+
43 => 'Dana Larson Sr.',
137+
42 => 'Dax Larkin',
138+
], $page1->pluck('name', 'id')->all());
139+
140+
$this->assertSame([
141+
41 => 'Gudrun Larkin',
142+
40 => 'Otis Larson MD',
143+
39 => 'Linkwood Larkin',
144+
20 => 'Prof. Larry Prosacco DVM',
145+
12 => 'Reta Larkin',
146+
], $page2->pluck('name', 'id')->all());
147+
}
148+
149+
public function test_it_can_use_paginated_search_with_query_callback()
150+
{
151+
[$page1, $page2] = $this->itCanUsePaginatedSearchWithQueryCallback();
152+
153+
$this->assertSame([
154+
1 => 'Laravel Framework',
155+
44 => 'Amos Larson Sr.',
156+
43 => 'Dana Larson Sr.',
157+
42 => 'Dax Larkin',
158+
], $page1->pluck('name', 'id')->all());
159+
160+
$this->assertSame([
161+
41 => 'Gudrun Larkin',
162+
40 => 'Otis Larson MD',
163+
12 => 'Reta Larkin',
164+
], $page2->pluck('name', 'id')->all());
165+
}
166+
167+
protected static function scoutDriver(): string
168+
{
169+
return 'typesense';
170+
}
171+
}

0 commit comments

Comments
 (0)