diff --git a/src/Builder.php b/src/Builder.php index 7989dd41..7bacc297 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -22,6 +22,13 @@ class Builder */ public $query; + /** + * Optional callback before search execution. + * + * @var string + */ + public $callback; + /** * The custom index specified for the search. * @@ -48,12 +55,14 @@ class Builder * * @param \Illuminate\Database\Eloquent\Model $model * @param string $query + * @param Closure $callback * @return void */ - public function __construct($model, $query) + public function __construct($model, $query, $callback = null) { $this->model = $model; $this->query = $query; + $this->callback = $callback; } /** diff --git a/src/Engines/AlgoliaEngine.php b/src/Engines/AlgoliaEngine.php index f8c2e116..021b048e 100644 --- a/src/Engines/AlgoliaEngine.php +++ b/src/Engines/AlgoliaEngine.php @@ -105,9 +105,20 @@ public function paginate(Builder $builder, $perPage, $page) */ protected function performSearch(Builder $builder, array $options = []) { - return $this->algolia->initIndex( + $agolia = $this->algolia->initIndex( $builder->index ?: $builder->model->searchableAs() - )->search($builder->query, $options); + ); + + if ($builder->callback) { + return call_user_func( + $builder->callback, + $agolia, + $builder->query, + $options + ); + } + + return $agolia->search($builder->query, $options); } /** diff --git a/src/Engines/ElasticsearchEngine.php b/src/Engines/ElasticsearchEngine.php index d960b2b2..dccfec30 100644 --- a/src/Engines/ElasticsearchEngine.php +++ b/src/Engines/ElasticsearchEngine.php @@ -134,18 +134,18 @@ public function paginate(Builder $query, $perPage, $page) /** * Perform the given search on the engine. * - * @param Builder $query + * @param Builder $builder * @param array $options * @return mixed */ - protected function performSearch(Builder $query, array $options = []) + protected function performSearch(Builder $builder, array $options = []) { - $termFilters = []; + $filters = []; - $matchQueries[] = [ + $matches[] = [ 'match' => [ '_all' => [ - 'query' => $query->query, + 'query' => $builder->query, 'fuzziness' => 1 ] ] @@ -155,13 +155,13 @@ protected function performSearch(Builder $query, array $options = []) foreach ($options['filters'] as $field => $value) { if(is_numeric($value)) { - $termFilters[] = [ + $filters[] = [ 'term' => [ $field => $value, ], ]; } elseif(is_string($value)) { - $matchQueries[] = [ + $matches[] = [ 'match' => [ $field => [ 'query' => $value, @@ -170,20 +170,19 @@ protected function performSearch(Builder $query, array $options = []) ] ]; } - } } - $searchQuery = [ + $query = [ 'index' => $this->index, - 'type' => $query->model->searchableAs(), + 'type' => $builder->model->searchableAs(), 'body' => [ 'query' => [ 'filtered' => [ - 'filter' => $termFilters, + 'filter' => $filters, 'query' => [ 'bool' => [ - 'must' => $matchQueries + 'must' => $matches ] ], ], @@ -192,18 +191,22 @@ protected function performSearch(Builder $query, array $options = []) ]; if (array_key_exists('size', $options)) { - $searchQuery = array_merge($searchQuery, [ - 'size' => $options['size'], - ]); + $query['size'] = $options['size']; } if (array_key_exists('from', $options)) { - $searchQuery = array_merge($searchQuery, [ - 'from' => $options['from'], - ]); + $query['from'] = $options['from']; + } + + if ($builder->callback) { + return call_user_func( + $builder->callback, + $this->elasticsearch, + $query + ); } - return $this->elasticsearch->search($searchQuery); + return $this->elasticsearch->search($query); } /** diff --git a/src/Searchable.php b/src/Searchable.php index 6fcb6c9b..7dc94e94 100644 --- a/src/Searchable.php +++ b/src/Searchable.php @@ -79,11 +79,12 @@ public function queueRemoveFromSearch($models) * Perform a search against the model's indexed data. * * @param string $query + * @param Closure $callback * @return \Laravel\Scout\Builder */ - public static function search($query) + public static function search($query, $callback = null) { - return new Builder(new static, $query); + return new Builder(new static, $query, $callback); } /**