我已经为您的问题制定了解决方案。我将提交一个pull request
forScout
希望将其与官方软件包合并。
这种方法允许您在搜索中包含软删除模型:
App\User::search('search query string')->withTrashed()->get();
仅在搜索中显示软删除模型:
App\User::search('search query string')->onlyTrashed()->get();
您需要修改3个文件:
生成器.php
添加laravel\scout\src\Builder.php
以下内容:
/**
* Whether the search should include soft deleted models.
*
* @var boolean
*/
public $withTrashed = false;
/**
* Whether the search should only include soft deleted models.
*
* @var boolean
*/
public $onlyTrashed = false;
/**
* Specify the search should include soft deletes
*
* @return $this
*/
public function withTrashed()
{
$this->withTrashed = true;
return $this;
}
/**
* Specify the search should only include soft deletes
*
* @return $this
*/
public function onlyTrashed()
{
$this->onlyTrashed = true;
return $this;
}
/**
* Paginate the given query into a simple paginator.
*
* @param int $perPage
* @param string $pageName
* @param int|null $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function paginate($perPage = null, $pageName = 'page', $page = null)
{
$engine = $this->engine();
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$perPage = $perPage ?: $this->model->getPerPage();
$results = Collection::make($engine->map(
$rawResults = $engine->paginate($this, $perPage, $page), $this->model, $this->withTrashed, $this->onlyTrashed
)); // $this->withTrashed, $this->onlyTrashed is new
$paginator = (new LengthAwarePaginator($results, $engine->getTotalCount($rawResults), $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]));
return $paginator->appends('query', $this->query);
}
引擎.php
在laravel\scout\src\Engines\Engine.php
修改以下内容:
/**
* Map the given results to instances of the given model.
*
* @param mixed $results
* @param \Illuminate\Database\Eloquent\Model $model
* @param boolean $withTrashed // New
* @return \Illuminate\Database\Eloquent\Collection
*/
abstract public function map($results, $model, $withTrashed, $onlyTrashed); // $withTrashed, $onlyTrashed is new
/**
* Get the results of the given query mapped onto models.
*
* @param \Laravel\Scout\Builder $builder
* @return \Illuminate\Database\Eloquent\Collection
*/
public function get(Builder $builder)
{
return Collection::make($this->map(
$this->search($builder), $builder->model, $builder->withTrashed, $builder->onlyTrashed // $builder->withTrashed, $builder->onlyTrashed is new
));
}
最后,您只需要修改您的相关搜索引擎。我正在使用 Algolia,但该map
方法似乎与TNTSearch
.
AlgoliaEngine.php
在laravel\scout\src\Engines\AlgoliaEngine.php
修改map
方法以匹配abstract
我们上面修改的类:
/**
* Map the given results to instances of the given model.
*
* @param mixed $results
* @param \Illuminate\Database\Eloquent\Model $model
* @param boolean $withTrashed // New
* @return \Illuminate\Database\Eloquent\Collection
*/
public function map($results, $model, $withTrashed, $onlyTrashed) // $withTrashed, $onlyTrashed is new
{
if (count($results['hits']) === 0) {
return Collection::make();
}
$keys = collect($results['hits'])
->pluck('objectID')->values()->all();
$modelQuery = $model->whereIn(
$model->getQualifiedKeyName(), $keys
);
if ($withTrashed) $modelQuery->withTrashed(); // This is where the query will include deleted items, if specified
if ($onlyTrashed) $modelQuery->onlyTrashed(); // This is where the query will only include deleted items, if specified
$models = $modelQuery->get()->keyBy($model->getKeyName());
return Collection::make($results['hits'])->map(function ($hit) use ($model, $models) {
$key = $hit['objectID'];
if (isset($models[$key])) {
return $models[$key];
}
})->filter();
}
TNTSearchEngine.php
/**
* Map the given results to instances of the given model.
*
* @param mixed $results
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return Collection
*/
public function map($results, $model, $withTrashed, $onlyTrashed)
{
if (count($results['ids']) === 0) {
return Collection::make();
}
$keys = collect($results['ids'])->values()->all();
$model_query = $model->whereIn(
$model->getQualifiedKeyName(), $keys
);
if ($withTrashed) $model_query->withTrashed();
if ($onlyTrashed) $model_query->onlyTrashed();
$models = $model_query->get()->keyBy($model->getKeyName());
return collect($results['ids'])->map(function ($hit) use ($models) {
if (isset($models[$hit])) {
return $models[$hit];
}
})->filter();
}
让我知道它是如何工作的。
注意:这种方法仍然需要您withoutSyncingToSearch
在删除模型时使用该方法手动暂停同步;否则搜索条件将更新为unsearchable()
.