[扩展推荐] 为 Laravel Eloquent 提供搜索支持

翻译 godruoyi ⋅ 于 1周前 ⋅ 657 阅读 ⋅ 原文地址
这是一篇社区协同翻译的文章,已完成翻译,更多信息请点击 协同翻译介绍

file

在这个系列的第一部分 https://github.com/jarektkaczyk/eloquence – 这个包允许以更加简单的管理方式来使用 Eloquent 模型 - 接下来我将向你介绍 Builder 类的可搜索特性。

假设一个拥有简单好友关系的应用:

// 用户模型

// 多对多关联
public function friends()
{
   return $this->belongsToMany(static::class, 'friends', 'user_id', 'friend_id');
}

// 1-1 relation
public function profile()
{
   return $this->hasOne(Profile::class);
}

一个简单的基于用户为核心的表 usersfriends 表作为好友多对多关联表,这对于演示来说是足够的。 在用户表中我们只存储邮箱和用户名,在用户简介表 profiles 中存储用户的真实数据比如用户的名字、姓氏(first_name, last_name)等。

Explorer 翻译于 1周前

显然密码、时间戳等其他相关的字段不是我们现在应该关心的内容。

现在, 为了找到一个人,我们可以使用几个字段的组合:users.username, users.email, profiles.first_name, profiles.last_name, friends.first_name, friends.last_name

以下是原始的 Eloquent 做法::

$name = strtolower(Input::get('query'));

$matchingUsers = User::where(function ($q) use ($name) {
      $q->where('email', 'like', '%'.str_replace(' ', '', $name).'%')
        ->orWhere('username', 'like', "%{$name}%")
        ->orWhereHas('profile', function ($q) {
          $q->where(function ($q) {
            $q->where('first_name', 'like', "%{$name}%")
              ->orWhere('last_name', 'like', "%{$name}%");
        });
      });
    })->get();
Explorer 翻译于 1周前

它很简单但是缺乏关键的搜索元素 - 相关性分数,也使得搜索朋友行不通。

像这样的查询返回分数需要一些计算,但是很显现,我们没有必要再创造一个谷歌哈😉

不过,理论上我们喜欢这样的方式:

$name = 'john doe';

$matchingUsers = User::search($name, [
    'profile.last_name' => 20,
    'email' => 10,
    'username' => 10,
    'profile.first_name' => 5,
    'friends.username' => 2,
    'friends.email' => 2,
    'friends.profile.first_name' => 1,
    'friends.profile.last_name' => 1,
  ])->get()

//如果这些字段不轻易变动,那么在模型中定义下它们:
protected $searchableColumns = [
    'profile.last_name' => 20,
    'email' => 10,
    'username' => 10,
    'profile.first_name' => 5,
    'friends.username' => 2,
    'friends.email' => 2,
    'friends.profile.first_name' => 1,
    'friends.profile.last_name' => 1,
];

//然后简单地调用
User::search($name)->get()

这些列都是定义在模型中的普通关联映射,只需要这些。每个列对应的数字是它的权重,我们通过分数来定义它们的重要性。

Eloquence\Builder 这个包的工作原理是自动地加入关联表格,添加一些履行条款并且通过关联搜索排序结果。

这个功能和得分算法的创意都是基于这个包 https://github.com/nicolaslopezj/searchable ,但它更加灵活易于使用,更重要的是速度提高了四倍(甚至更高,实际依赖查询中附加的 where 子句)

JeremyKuang 翻译于 1周前

通过下面几个例子,你可以知道怎么使用这种方式来搜索。这个搜索方式同样会提升搜索速度 – 全文搜索不会使用索引,所以在大表或者多个连接表进行搜索时会变的很慢。

假如你的需求是这样,你想禁用掉全文索引,并且使用右侧通配符 ( word *) 来代替全文索引。

// 全文搜索 + 指定字段搜索权重:
User::search('john doe', ['email' => 10, 'profile.name' => 20, 'friends.profile.name' => 5])->take(10)->get()

// 全文搜索默认的字段:
User::search('"going to LA"')->get()

// 指定搜索
User::search('"going to LA"', $fulltext = false)->get()

// 通配符搜索
User::search(['going to *', '*LA*', '*NY*'], $fulltext = false)->get()
miss201 翻译于 1周前

原文地址:https://softonsofa.com/laravel-searchabl...

译文地址:https://laravel-china.org/topics/13041/e...


本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

本帖已被设为精华帖!
回复数量: 0
    暂无评论~~
    您需要登陆以后才能留下评论!

    Composer 中国全量镜像

    Top 100 扩展包

    Lumen 中文文档

    Laravel 速查表

    Laravel 中文文档

    Laravel 项目开发规范

    Laravel 开发环境部署

    社区文档撰写指南

    TDD 构建 Laravel 论坛笔记

    PHP PSR 标准规范

    PHP 设计模式全集

    Dingo API 中文文档