testmonitor/eloquent-searchable

一个Laravel扩展包,为Eloquent模型添加搜索功能,支持多种搜索技术,如精确匹配和部分匹配。

dev-main 2024-09-16 14:36 UTC

This package is auto-updated.

Last update: 2024-09-16 14:36:07 UTC


README

Latest Stable Version codecov StyleCI License

为Eloquent模型提供搜索功能的包。您可以定义使用不同搜索技术的搜索方面,例如精确匹配或部分匹配。

它受到了Spatie的查询构建器的极大启发,可以与该包一起使用。

目录

安装

此包可以通过Composer安装

$ composer require testmonitor/eloquent-searchable

接下来,发布配置文件

$ php artisan vendor:publish --tag=eloquent-searchable

配置文件允许您更改HTTP参数名称以及最小查询长度。

使用

要为您的Eloquent模型添加可搜索功能,请按照以下步骤操作

  1. 在模型(s)中使用特质 TestMonitor\Searchable\Searchable
  2. 包括与一个或多个搜索方面一起使用的搜索Using作用域。

将可搜索特质添加到您想要使其可搜索的模型上

use Illuminate\Database\Eloquent\Model;
use TestMonitor\Searchable\Searchable;

class User extends Model
{
    use Searchable;

    // ...
}

接下来,包括带有 SearchAspectssearchUsing 作用域以定义您的搜索策略

use App\Models\User;
use Illuminate\Routing\Controller;
use TestMonitor\Searchable\Aspects\SearchAspect;

class UsersController extends Controller
{
    public function index()
    {
        return User::query()
            ->seachUsing([
                SearchAspect::exact('first_name'),
                SearchAspect::exact('last_name'),
                SearchAspect::partial('email'),
            ])
            ->get();
    }
}

在这个例子中,控制器提供了一个通过一组用户进行搜索的方法

  • 使用“精确”策略搜索第一个和最后一个名字。只有精确匹配将被返回。
  • 使用“部分”匹配策略搜索电子邮件字段。当查询词出现在电子邮件地址中时,它将被返回。

搜索查询自动从HTTP请求中派生出来。您可以在配置文件中修改HTTP查询参数。默认情况下,使用 query 名称。

方面

一个模型的搜索策略由搜索方面定义。方面定义了一个匹配配置。例如,精确搜索方面在提供的属性上执行精确搜索。

Eloquent Searcheable提供了多个方面。您还可以使用自定义方面定义自己的匹配配置。

精确匹配

精确搜索方面将仅返回等于搜索词的匹配项。

use App\Models\Post;
use Illuminate\Routing\Controller;
use TestMonitor\Searchable\Aspects\SearchAspect;

class PostsController extends Controller
{
    public function index()
    {
        return Post::query()
            ->seachUsing([
                SearchAspect::exact(name: 'title'),
            ])
            ->get();
    }
}

部分匹配

部分搜索方面返回在给定属性中任何位置出现搜索查询的匹配项。

use App\Models\Post;
use Illuminate\Routing\Controller;
use TestMonitor\Searchable\Aspects\SearchAspect;

class PostsController extends Controller
{
    public function index()
    {
        return Post::query()
            ->seachUsing([
                SearchAspect::partial(name: 'title'),
            ])
            ->get();
    }
}

JSON匹配

JSON搜索方面返回在给定JSON属性中任何位置出现搜索查询的匹配项。

use App\Models\Post;
use Illuminate\Routing\Controller;
use TestMonitor\Searchable\Aspects\SearchAspect;

class PostsController extends Controller
{
    public function index()
    {
        return Post::query()
            ->seachUsing([
                SearchAspect::json(name: 'settings'),
            ])
            ->get();
    }
}

前缀匹配

前缀方面结合了精确和部分策略,并具有从搜索查询中删除一个或多个字符的能力。这可以在您的应用程序为用户提供带有前缀的增量代码(例如,ISSUE-12)但仅在数据库中存储数字(即数字12)时很有用。

默认情况下,使用部分匹配策略。使用 exact 参数,您可以启用精确匹配。

use App\Models\Issue;
use Illuminate\Routing\Controller;
use TestMonitor\Searchable\Aspects\SearchAspect;

class IssuesController extends Controller
{
    public function index()
    {
        return Issue::query()
            ->seachUsing([
                SearchAspect::prefix(name: 'code', prefix: 'ISSUE-', exact: true),
                SearchAspect::prefix(name: 'code', prefix: 'ISSUE-'),
            ])
            ->get();
    }
}

自定义方面

您可以通过创建一个实现 TestMonitor\Searchable\Contracts\Search 合约的类来创建自己的搜索方面。

让我们实现一个新的搜索方面:匹配属性的开始部分的策略。您的自定义搜索方面可能看起来像这样

use TestMonitor\Searchable\Weights;
use Illuminate\Database\Eloquent\Builder;
use TestMonitor\Searchable\Contracts\Search;

class StartsWithSearch implements Search
{
    /**
     * @param \Illuminate\Database\Eloquent\Builder<\Illuminate\Database\Eloquent\Model> $query
     * @param \TestMonitor\Searchable\Weights $weights
     * @param string $property
     * @param string $term
     * @param int $weight
     */
    public function __invoke(Builder $query, Weights $weights, string $property, string $term, int $weight = 1): void
    {
        $query->where($property, 'like', "{$term}%");
    }
}

要使用此自定义方面,请像这样在搜索标准中定义它

use App\Models\Post;
use Illuminate\Routing\Controller;
use App\Search\Aspects\CustomSearch;
use TestMonitor\Searchable\Aspects\SearchAspect;

class PostsController extends Controller
{
    public function index()
    {
        return Post::query()
            ->seachUsing([
                SearchAspect::custom('name', new CustomSearch),
            ])
            ->get();
    }
}

搜索权重

可选地,您可以使用搜索权重。权重优先级排序搜索标准,将权重更高的结果放置在顶部。

让我们使Post模型可搜索,并使用以下标准

  • 在帖子的标题中部分匹配关键词应排在最前面。
  • 在摘要中部分匹配关键词应排在任何标题匹配之后。
  • 在描述中部分匹配关键词应排在其他任何标准之后。

以下是一个实现这些标准的示例

use App\Models\Post;
use Illuminate\Routing\Controller;
use TestMonitor\Searchable\Aspects\SearchAspect;

class PostsController extends Controller
{
    public function index()
    {
        return Post::query()
            ->seachUsing([
                SearchAspect::partial(name: 'title', weight: 20),
                SearchAspect::partial(name: 'summary', weight: 10),
                SearchAspect::partial('description'),
            ])
            ->get();
    }
}

搜索相关模型

使用点号表示法遍历相关模型属性。

假设你想根据博客的标题和描述搜索你的帖子。以下是一个实现这些标准的示例

use App\Models\Post;
use Illuminate\Routing\Controller;
use TestMonitor\Searchable\Aspects\SearchAspect;

class PostsController extends Controller
{
    public function index()
    {
        return Post::query()
            ->seachUsing([
                SearchAspect::exact('blog.title'),
                SearchAspect::partial('blog.description'),
            ])
            ->get();
    }
}

测试

该包包含集成测试。您可以使用PHPUnit运行它们。

$ vendor/bin/phpunit

变更日志

有关更多信息,请参阅变更日志

贡献

有关贡献细节,请参阅贡献指南

鸣谢

许可

MIT许可(MIT)。有关更多信息,请参阅许可协议