Skip to content

Commit 8f202f8

Browse files
committed
Added lazy tests.
1 parent 425f79b commit 8f202f8

File tree

2 files changed

+120
-4
lines changed

2 files changed

+120
-4
lines changed

src/ElasticsearchEngine.php

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Database\Eloquent\Collection;
77
use Laravel\Scout\Builder;
88
use Laravel\Scout\Engines\Engine;
9+
use Illuminate\Support\LazyCollection;
910

1011
class ElasticsearchEngine extends Engine
1112
{
@@ -234,14 +235,79 @@ public function map(Builder $builder, $results, $model)
234235
if ($results['hits']['total'] === 0) {
235236
return $model->newCollection();
236237
}
238+
237239
$keys = collect($results['hits']['hits'])->pluck('_id')->values()->all();
238240

239241
return $model->getScoutModelsByIds(
240242
$builder,
241243
$keys
242244
)->filter(function ($model) use ($keys) {
243-
return in_array($model->getScoutKey(), $keys);
244-
});
245+
return in_array($model->getScoutKey(), $keys);
246+
});
247+
}
248+
249+
/**
250+
* Map the given results to instances of the given model via a lazy collection.
251+
*
252+
* @param \Laravel\Scout\Builder $builder
253+
* @param mixed $results
254+
* @param \Illuminate\Database\Eloquent\Model $model
255+
* @return \Illuminate\Support\LazyCollection
256+
*/
257+
public function lazyMap(Builder $builder, $results, $model)
258+
{
259+
if (intval($results['hits']['total']) === 0) {
260+
return LazyCollection::make($model->newCollection());
261+
}
262+
263+
$objectIds = collect($results['hits']['hits'])->pluck('_id')->values()->all();
264+
265+
$objectIdPositions = array_flip($objectIds);
266+
267+
return $model->queryScoutModelsByIds(
268+
$builder, $objectIds
269+
)->cursor()->filter(function ($model) use ($objectIds) {
270+
return in_array($model->getScoutKey(), $objectIds);
271+
})->sortBy(function ($model) use ($objectIdPositions) {
272+
return $objectIdPositions[$model->getScoutKey()];
273+
})->values();
274+
}
275+
276+
/**
277+
* Create a search index.
278+
*
279+
* @param string $name
280+
* @param array $options
281+
* @return mixed
282+
*/
283+
public function createIndex($name, array $options = [])
284+
{
285+
throw new Exception('Database indexes are created automatically upon adding objects.');
286+
}
287+
288+
/**
289+
* Delete a search index.
290+
*
291+
* @param string $name
292+
* @return mixed
293+
*/
294+
public function deleteIndex($name)
295+
{
296+
$this->elastic->bulk([
297+
'body' => [
298+
[
299+
'delete' => [
300+
'_index' => $name,
301+
/**
302+
* @deprecated Document mapping types scheduled deprecated in
303+
* elasticsearch 6.0 will be removed in 8.0.
304+
* https://bit.ly/2TZVZvq
305+
*/
306+
'_type' => $name,
307+
],
308+
]
309+
]
310+
]);
245311
}
246312

247313
/**

tests/ElasticsearchEngineTest.php

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Laravel\Scout\Builder;
88
use Mockery;
99
use Tests\Fixtures\TestModel;
10+
use Illuminate\Support\LazyCollection;
1011

1112
class ElasticsearchEngineTest extends AbstractTestCase
1213
{
@@ -88,7 +89,7 @@ public function test_builder_callback_can_manipulate_search_parameters_to_elasti
8889
{
8990
/** @var \Elasticsearch\Client|\Mockery\MockInterface $client */
9091
$client = Mockery::mock(\Elasticsearch\Client::class);
91-
$client->shouldReceive('search')->with('modified_by_callback');
92+
$client->shouldReceive('search')->with(['modified_by_callback']);
9293

9394
$engine = new ElasticsearchEngine($client);
9495
$builder = new \Laravel\Scout\Builder(
@@ -97,7 +98,7 @@ public function test_builder_callback_can_manipulate_search_parameters_to_elasti
9798
function (\Elasticsearch\Client $client, $query, $params) {
9899
$this->assertNotEmpty($params);
99100
$this->assertEquals('huayra', $query);
100-
$params = 'modified_by_callback';
101+
$params = ['modified_by_callback'];
101102

102103
return $client->search($params);
103104
}
@@ -131,4 +132,53 @@ public function test_map_correctly_maps_results_to_models()
131132

132133
$this->assertEquals(1, count($results));
133134
}
135+
136+
public function test_lazy_map_correctly_maps_results_to_models()
137+
{
138+
$client = Mockery::mock('Elasticsearch\Client');
139+
$engine = new ElasticsearchEngine($client);
140+
141+
$builder = Mockery::mock(Builder::class);
142+
143+
$model = Mockery::mock('Illuminate\Database\Eloquent\Model');
144+
$model->shouldReceive('getScoutKey')->andReturn('1');
145+
$model->shouldReceive('queryScoutModelsByIds')->andReturn($model);
146+
$model->shouldReceive('cursor')->andReturn($model);
147+
$model->shouldReceive('filter')->andReturn($model);
148+
$model->shouldReceive('sortBy')->andReturn($model);
149+
$model->shouldReceive('values')->andReturn(LazyCollection::make([1]));
150+
151+
$results = $engine->lazyMap($builder, [
152+
'hits' => [
153+
'total' => 1,
154+
'hits' => [
155+
[
156+
'_id' => '1',
157+
],
158+
],
159+
],
160+
], $model);
161+
162+
$this->assertCount(1, $results);
163+
}
164+
165+
public function test_lazy_map_correctly_maps_empty()
166+
{
167+
$client = Mockery::mock('Elasticsearch\Client');
168+
$engine = new ElasticsearchEngine($client);
169+
170+
$builder = Mockery::mock(Builder::class);
171+
172+
$model = Mockery::mock('Illuminate\Database\Eloquent\Model');
173+
$model->shouldReceive('newCollection')->andReturn(collect([]));
174+
175+
$results = $engine->lazyMap($builder, [
176+
'hits' => [
177+
'total' => 0,
178+
'hits' => [],
179+
],
180+
], $model);
181+
182+
$this->assertCount(0, $results);
183+
}
134184
}

0 commit comments

Comments
 (0)