如何使用 Eloquent 实现包含包含的搜索

Posted

技术标签:

【中文标题】如何使用 Eloquent 实现包含包含的搜索【英文标题】:How to implement search with contains using Eloquent 【发布时间】:2020-05-21 02:52:38 【问题描述】:

我用 Eloquent 像这样创建一个搜索查询:

User::where('firstName', 'like', '%' . $search_value . '%')
      ->orWhere('lastName', 'like', '%' . $search_value . '%')
      ->get();

这是工作。但我需要使用包含进行搜索。例如,如果我的搜索值为hello world,我应该找到值为World! Okay, hello 的行。

我该怎么做?

【问题讨论】:

您可以使用 Laravel 宏并创建一个宏来完全满足您的需求。结帐freek.dev/… 【参考方案1】:

1) 您可以使用范围方法创建搜索特征。

App\Traits\Searchable.php:

namespace App\Traits;

trait Searchable

    public function scopeSearch($builder, $query, $columns = null)
    
        if($query)
            $words = explode(' ', $query);
            $words = array_filter($words);

            if(!$columns)
                $columns = $this->searchable;
            

            $builder->where(function ($builder) use ($words, $columns) 
                foreach ($words as $word) 
                    $builder->where(function ($builder) use ($word, $columns) 
                        foreach ($columns as $column) 
                            if (strpos($column, '.') !== false) 
                                [$relation, $column] = explode('.', $column);
                                $builder->orWhereHas($relation, function ($query) use ($column, $word) 
                                    $query->where($column, 'like', '%' . $word . '%');
                                );
                             else 
                                $builder->oRwhere($this->getTable() . '.' . $column, 'like', '%' . $word . '%');
                            
                        
                    );
                
            );
        
    

2) 将Searchable 特征添加到模型和$searchable 具有可搜索列的属性。

App\Model\User.php:

class User extends Authenticatable

    use Searchable;

    public $searchable = ['firstName', 'lastName'];

3) 使用搜索范围:

$users = User::search($search_value)->get();

或带有特定列:

$users = User::search($search_value, ['firstName', 'lastName', 'role.title'])->get();

现在您可以将此特征用于您的所有模型,并通过模型列和模型关系列进行搜索。

第一个参数接受查询,第二个参数接受带有点的列或关系列 (relation.column)。

我们将查询拆分为单词并在不同列中搜索所有匹配的单词。

【讨论】:

【参考方案2】:

所以最简单的方法是使用 Eloquent 宏:

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro('whereLike', function(string $attribute, string $searchTerm) 
   return $this->orWhere($attribute, 'LIKE', "%$searchTerm%");
);

现在您可以像这样搜索模型:

User::query()
   ->whereLike('name', $searchTerm)
   ->whereLike('email', $searchTerm)
   ->get();

关于这个主题的更多信息:https://freek.dev/1182-searching-models-using-a-where-like-query-in-laravel 和 https://tighten.co/blog/the-magic-of-laravel-macros

【讨论】:

以上是关于如何使用 Eloquent 实现包含包含的搜索的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Eloquent 实现自引用数据透视表关系

如何在包含具有 Eloquent 的对象数组的 json 字段中求和

如何在 Laravel Eloquent 中获取包含数组的 JSON 对象的值?

如何在 Laravel 中使用多表查询而不使用 Eloquent 关系

如何根据 laravel eloquent orm 中的两列进行查询

如何在使用 eloquent 时排除某些列