Как реализовать поиск по содержанию с помощью Eloquent - PullRequest
1 голос
/ 05 февраля 2020

Я создаю поисковый запрос с Eloquent следующим образом:

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

Это работа. Но мне нужно искать с содержанием. Например, если мое значение поиска hello world, я должен найти строку со значением World! Okay, hello.

Как я могу это сделать?

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

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 trait to model и $searchable свойство с доступными для поиска столбцами.

App \ Model \ User. php:

class User extends Authenticatable
{
    use Searchable;

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

3) Используйте область поиска:

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

или с указанными c столбцами:

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

Теперь вы можете использовать эту черту со всеми вашими моделями и столбцами моделей поискового лотка и столбцами отношений модели.

Первый аргумент принимает запрос, второй аргумент принимает столбцы или столбцы отношений с точками (relation.column).

Мы разбиваем запрос на слова и ищем совпадения всех слов в разных столбцах.

0 голосов
/ 05 февраля 2020

Таким образом, самый простой способ достичь этого - использовать Eloquent Macros:

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

...