spatie/laravel-searchable

以实用方式搜索模型和其他来源

1.12.0 2024-03-13 23:19 UTC

README

Latest Version on Packagist run-tests Total Downloads

此包可轻松从各种来源获取结构化搜索。以下是我们搜索一些模型的示例。我们已经在模型本身上进行了一些小准备。

$searchResults = (new Search())
   ->registerModel(User::class, 'name')
   ->registerModel(BlogPost::class, 'title')
   ->search('john');

搜索将不区分大小写。现在 $searchResults 包含所有在 name 属性中包含 johnUser 模型以及在 title 属性中包含 'john' 的 BlogPost

在您的视图中,您现在可以遍历搜索结果

<h1>Search</h1>

There are {{ $searchResults->count() }} results.

@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;
}

您只需要为每个可搜索模型添加一个返回 SearchResult 实例的 getSearchResult 方法。以下是一个博客帖子模型的示例。

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 属性中包含 johnUser 模型。

您也可以传递多个属性进行搜索

// use multiple model attributes

$searchResults = (new Search())
   ->registerModel(User::class, 'first_name', 'last_name')
   ->search('john');
   
// or use an array of model attributes

$searchResults = (new Search())
   ->registerModel(User::class, ['first_name', 'last_name'])
   ->search('john');

为了获得更细粒度的控制,您还可以使用可调用函数。这样,您还可以搜索精确匹配、应用作用域、预加载关系,甚至像使用查询构建器一样过滤查询。

$search = (new Search())
   ->registerModel(User::class, function(ModelSearchAspect $modelSearchAspect) {
       $modelSearchAspect
          ->addSearchableAttribute('name') // return results for partial matches on usernames
          ->addExactSearchableAttribute('email') // only return results that exactly match the e-mail address
          ->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>Search</h1>

There are {{ $searchResults->count() }} results.

@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 = 'custom named aspect';
}

测试

composer test

变更日志

请参阅变更日志了解最近发生了哪些变化。

贡献

请参阅贡献指南了解详细信息。

安全性

如果您发现了关于安全性的错误,请发送邮件至security@spatie.be,而不是使用问题跟踪器。

致谢

许可证

MIT许可证(MIT)。请参阅许可证文件获取更多信息。