这个包可以让你轻松地从各种来源获得结构化搜索。以下是一个搜索模型的示例。我们已经对模型本身做了一些小的准备工作。
$searchResults = (new Search()) ->registerModel(User::class, 'name') ->registerModel(BlogPost::class, 'title') ->search('john');
搜索将不区分大小写进行。$searchResults
现在包含了所有 name
属性中包含 john
的 User
模型和 title
属性中包含 'john' 的 BlogPost
模型。
在你的视图中,你现在可以遍历搜索结果:
<h1>搜索</h1> 共有 {{ $searchResults->count() }} 个结果。 @foreach($searchResults->groupByType() as $type => $modelSearchResults) <h2>{{ $type }}</h2> @foreach($modelSearchResults as $searchResult) <ul> <li><a href="{{ $searchResult->url }}">{{ $searchResult->title }}</a></li> </ul> @endforeach @endforeach
在这个例子中我们使用了模型,但你可以轻松地为外部 API、文件列表或值数组添加搜索方面。
我们投入了大量资源来创建一流的开源包。你可以通过购买我们的付费产品来支持我们。
我们非常感谢你从你的家乡寄给我们一张明信片,提到你正在使用我们的哪个包。你可以在我们的联系页面找到我们的地址。我们会在我们的虚拟明信片墙上发布所有收到的明信片。
你可以通过 composer 安装这个包:
composer require spatie/laravel-searchable
为了搜索模型,你需要让它们实现 Searchable
接口。
namespace Spatie\Searchable; interface Searchable { public function getSearchResult(): SearchResult; }
你只需要为每个可搜索的模型添加一个 getSearchResult
方法,该方法必须返回 SearchResult
的实例。以下是博客文章模型的示例。
use Spatie\Searchable\Searchable; use Spatie\Searchable\SearchResult; class BlogPost extends Model implements Searchable { public function getSearchResult(): SearchResult { $url = route('blogPost.show', $this->slug); return new \Spatie\Searchable\SearchResult( $this, $this->title, $url ); } }
准备好模型后,你可以像这样搜索它们:
$searchResults = (new Search()) ->registerModel(User::class, 'name') ->search('john');
搜索将不区分大小写。$searchResults
现在包含所有在 name
属性中包含 john
的 User
模型。
您也可以传递多个属性进行搜索:
// 使用多个模型属性 $searchResults = (new Search()) ->registerModel(User::class, 'first_name', 'last_name') ->search('john'); // 或使用模型属性数组 $searchResults = (new Search()) ->registerModel(User::class, ['first_name', 'last_name']) ->search('john');
要获得更精细的控制,您还可以使用可调用函数。通过这种方式,您还可以搜索完全匹配项、应用作用域、预加载关系,甚至像使用查询构建器一样过滤查询。
$search = (new Search()) ->registerModel(User::class, function(ModelSearchAspect $modelSearchAspect) { $modelSearchAspect ->addSearchableAttribute('name') // 返回用户名部分匹配的结果 ->addExactSearchableAttribute('email') // 只返回与电子邮件地址完全匹配的结果 ->active() ->has('posts') ->with('roles'); });
您不仅限于注册基本模型作为搜索方面。您可以通过扩展 SearchAspect
类轻松创建自己的自定义搜索方面。
考虑以下用于搜索外部 API 的自定义搜索方面:
class OrderSearchAspect extends SearchAspect { public function getResults(string $term): Collection { return OrderApi::searchOrders($term); } }
以下是如何使用它:
$searchResults = (new Search()) ->registerAspect(OrderSearchAspect::class) ->search('john');
可以通过在执行搜索前调用 limitAspectResults
来限制每个方面返回的结果数量。
$searchResults = (new Search()) ->registerAspect(BlogPostAspect::class) ->limitAspectResults(50) ->search('How To');
以下是渲染搜索结果的示例:
<h1>搜索</h1> 共有 {{ $searchResults->count() }} 个结果。 @foreach($searchResults->groupByType() as $type => $modelSearchResults) <h2>{{ $type }}</h2> @foreach($modelSearchResults as $searchResult) <ul> <a href="{{ $searchResult->url }}">{{ $searchResult->title }}</a> </ul> @endforeach @endforeach
您可以通过在模型或自定义搜索方面上添加公共属性 $searchableType
来自定义 $type
class BlogPost extends Model implements Searchable { public $searchableType = '自定义命名方面'; }
composer test
请查看 CHANGELOG 以获取有关最近变更的更多信息。