diff --git a/composer.json b/composer.json index c8eacc3..1d30a52 100644 --- a/composer.json +++ b/composer.json @@ -11,11 +11,11 @@ ], "minimum-stability": "dev", "require": { - "php": ">=5.6.4", - "laravel/scout": "^7.1", + "php": ">=7.0", + "laravel/scout": "~6.0", "teamtnt/tntsearch": "~1.0", - "illuminate/support": "^6.0", - "illuminate/database": "^6.0" + "illuminate/support": "~5.4", + "illuminate/database": "~5.4" }, "require-dev": { "mockery/mockery": "~0.9", diff --git a/src/Engines/TNTSearchEngine.php b/src/Engines/TNTSearchEngine.php index e1b7ee9..c1eb188 100644 --- a/src/Engines/TNTSearchEngine.php +++ b/src/Engines/TNTSearchEngine.php @@ -2,10 +2,9 @@ namespace Vanry\Scout\Engines; -use Illuminate\Database\Eloquent\Collection; use Laravel\Scout\Builder; -use Laravel\Scout\Engines\Engine; use TeamTNT\TNTSearch\TNTSearch; +use Laravel\Scout\Engines\Engine; use TeamTNT\TNTSearch\Exceptions\IndexNotFoundException; class TNTSearchEngine extends Engine @@ -33,23 +32,24 @@ public function __construct(TNTSearch $tnt) /** * Update the given model in the index. * - * @param Collection $models + * @param \Illuminate\Database\Eloquent\Collection $models * * @return void */ public function update($models) { - $this->initIndex($models->first()); - $this->tnt->selectIndex("{$models->first()->searchableAs()}.index"); + $model = $models->first(); + + $this->initIndex($model); + $index = $this->tnt->getIndex(); - $index->setTokenizer($this->tnt->tokenizer); - $index->setPrimaryKey($models->first()->getKeyName()); - if (isset($this->tnt->config['stopwords'])) { - $index->setStopWords((array) $this->tnt->config['stopwords']); - } + $index->setPrimaryKey($model->getKeyName()); + $index->setTokenizer($this->tnt->tokenizer); + $index->setStopWords($this->tnt->config['stopwords'] ?? []); $index->indexBeginTransaction(); + $models->each(function ($model) use ($index) { $array = $model->toSearchableArray(); @@ -63,24 +63,23 @@ public function update($models) $index->insert($array); } }); + $index->indexEndTransaction(); } /** * Remove the given model from the index. * - * @param Collection $models + * @param \Illuminate\Database\Eloquent\Collection $models * * @return void */ public function delete($models) { $this->initIndex($models->first()); + $models->each(function ($model) { - $this->tnt->selectIndex("{$model->searchableAs()}.index"); - $index = $this->tnt->getIndex(); - $index->setPrimaryKey($model->getKeyName()); - $index->delete($model->getKey()); + $this->tnt->getIndex()->delete($model->getKey()); }); } @@ -139,26 +138,23 @@ public function paginate(Builder $builder, $perPage, $page) */ protected function performSearch(Builder $builder, array $options = []) { + $this->builder = $builder; + $index = $builder->index ?: $builder->model->searchableAs(); - $limit = $builder->limit ?: 10000; + $this->tnt->selectIndex("{$index}.index"); - $this->builder = $builder; $this->tnt->asYouType = $builder->model->asYouType ?: false; if ($builder->callback) { - return call_user_func( - $builder->callback, - $this->tnt, - $builder->query, - $options - ); - } - if (isset($this->tnt->config['searchBoolean']) ? $this->tnt->config['searchBoolean'] : false) { - return $this->tnt->searchBoolean($builder->query, $limit); - } else { - return $this->tnt->search($builder->query, $limit); + return call_user_func($builder->callback, $this->tnt, $builder->query, $options); } + + $limit = $builder->limit ?: 10000; + + return ($this->tnt->config['searchBoolean'] ?? false) + ? $this->tnt->searchBoolean($builder->query, $limit) + : $this->tnt->search($builder->query, $limit); } /** @@ -168,20 +164,19 @@ protected function performSearch(Builder $builder, array $options = []) * @param mixed $results * @param \Illuminate\Database\Eloquent\Model $model * - * @return Collection + * @return \Illuminate\Database\Eloquent\Collection */ public function map(Builder $builder, $results, $model) { if (count($results['ids']) === 0) { - return Collection::make(); + return $model->newCollection(); } $keys = collect($results['ids'])->values()->all(); + + $models = $model->whereIn($model->getQualifiedKeyName(), $keys)->get()->keyBy($model->getKeyName()); + $fieldsWheres = array_keys($this->builder->wheres); - $models = $model->whereIn( - $model->getQualifiedKeyName(), - $keys - )->get()->keyBy($model->getKeyName()); return collect($results['ids'])->map(function ($hit) use ($models) { return $models->has($hit) ? $models[$hit] : null; @@ -189,7 +184,6 @@ public function map(Builder $builder, $results, $model) return ! is_null($model) && array_reduce($fieldsWheres, function ($carry, $item) use ($model) { return $carry && $model[$item] == $this->builder->wheres[$item]; }, true); - ; }); } @@ -218,26 +212,34 @@ public function getTotalCount($results) public function initIndex($model) { - $indexName = $model->searchableAs(); - - if (! file_exists($storage = $this->tnt->config['storage'])) { - mkdir($storage, 0777, true); - chmod($storage, 0777); + if (! file_exists($this->tnt->config['storage'])) { + mkdir($this->tnt->config['storage'], 0777, true); } - if (! file_exists($storage."/{$indexName}.index")) { - $indexer = $this->tnt->createIndex("$indexName.index"); + $indexPath = $this->getIndexPath($model); + + $indexName = basename($indexPath); + + if (! file_exists($indexPath)) { + $indexer = $this->tnt->createIndex($indexName); $indexer->setDatabaseHandle($model->getConnection()->getPdo()); $indexer->setPrimaryKey($model->getKeyName()); } + + $this->tnt->selectIndex($indexName); } public function flush($model) { - $storage = $this->tnt->config['storage'] . "{$model->searchableAs()}.index"; + $indexPath = $this->getIndexPath($model); - if (file_exists($storage)) { - unlink($storage); + if (file_exists($indexPath)) { + unlink($indexPath); } } + + protected function getIndexPath($model) + { + return sprintf('%s/%s.index', $this->tnt->config['storage'], $model->searchableAs()); + } } diff --git a/src/TNTSearchScoutServiceProvider.php b/src/TNTSearchScoutServiceProvider.php index 2073e79..0c66d20 100644 --- a/src/TNTSearchScoutServiceProvider.php +++ b/src/TNTSearchScoutServiceProvider.php @@ -31,7 +31,7 @@ public function register() public function boot() { $this->app[EngineManager::class]->extend('tntsearch', function ($app) { - $tnt = new TNTSearch(); + $tnt = new TNTSearch; $driver = config('database.default'); $config = config('scout.tntsearch') + config("database.connections.{$driver}"); @@ -40,13 +40,18 @@ public function boot() $tnt->setTokenizer(app('tntsearch.tokenizer')->driver()); $tnt->setDatabaseHandle(app('db')->connection()->getPdo()); - $this->setFuzziness($tnt); $this->setAsYouType($tnt); + $this->setFuzziness($tnt); return new TNTSearchEngine($tnt); }); } + protected function setAsYouType($tnt) + { + $tnt->asYouType = config('scout.tntsearch.asYouType', $tnt->asYouType); + } + protected function setFuzziness($tnt) { $tnt->fuzziness = config('scout.tntsearch.fuzziness', $tnt->fuzziness); @@ -54,9 +59,4 @@ protected function setFuzziness($tnt) $tnt->fuzzy_prefix_length = config('scout.tntsearch.fuzzy.prefix_length', $tnt->fuzzy_prefix_length); $tnt->fuzzy_max_expansions = config('scout.tntsearch.fuzzy.max_expansions', $tnt->fuzzy_max_expansions); } - - protected function setAsYouType($tnt) - { - $tnt->asYouType = config('scout.tntsearch.asYouType', $tnt->asYouType); - } }