diff --git a/composer.json b/composer.json index 99239551..95601c1b 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "require": { "php": "^7.1.|^8.0", "elasticsearch/elasticsearch": ">=7.0 <=7.11.0", - "laravel/scout": "^7.0|^8.0" + "laravel/scout": "^7.0|^8.0|^9.0" }, "require-dev": { "phpunit/phpunit": "^7.0|^8.0", diff --git a/src/ElasticEngine.php b/src/ElasticEngine.php index 4cd2af2c..e2a4b2f3 100755 --- a/src/ElasticEngine.php +++ b/src/ElasticEngine.php @@ -6,11 +6,13 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Artisan; +use Illuminate\Support\LazyCollection; use Laravel\Scout\Builder; use Laravel\Scout\Engines\Engine; use ScoutElastic\Builders\SearchBuilder; use ScoutElastic\Facades\ElasticClient; use ScoutElastic\Indexers\IndexerInterface; +use ScoutElastic\Payloads\RawPayload; use ScoutElastic\Payloads\TypePayload; use stdClass; @@ -362,4 +364,86 @@ public function flush($model) ->orderBy($model->getScoutKeyName()) ->unsearchable(); } + + /** + * {@inheritdoc} + */ + public function lazyMap(Builder $builder, $results, $model): LazyCollection + { + if ($this->getTotalCount($results) === 0) { + return LazyCollection::make(); + } + + $scoutKeyName = $model->getScoutKeyName(); + + $columns = Arr::get($results, '_payload.body._source'); + + if (is_null($columns)) { + $columns = ['*']; + } else { + $columns[] = $scoutKeyName; + } + + $ids = $this->mapIds($results)->all(); + + $query = $model::usesSoftDelete() ? $model->withTrashed() : $model->newQuery(); + + $models = $query + ->whereIn($scoutKeyName, $ids) + ->when($builder->queryCallback, function ($query, $callback) { + return $callback($query); + }) + ->get($columns) + ->keyBy($scoutKeyName); + + $values = LazyCollection::make($results['hits']['hits']) + ->map(function ($hit) use ($models) { + $id = $hit['_id']; + + if (isset($models[$id])) { + $model = $models[$id]; + + if (isset($hit['highlight'])) { + $model->highlight = new Highlight($hit['highlight']); + } + + //add sort information to results for use + if (isset($hit['sort'])) { + $model->sortPayload = $hit['sort']; + } + + return $model; + } + }) + ->filter() + ->values(); + + return LazyCollection::wrap($values); + } + + /** + * {@inheritdoc} + */ + public function createIndex($name, array $options = []) + { + $payload = (new RawPayload) + ->set('index', $name) + ->get(); + + ElasticClient::indices() + ->create($payload); + } + + /** + * {@inheritdoc} + */ + public function deleteIndex($name) + { + $payload = (new RawPayload) + ->set('index', $name) + ->get(); + + ElasticClient::indices() + ->delete($payload); + } }