5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

laravel 姓 名が別カラムなので結合したり、キーワードが空白で区切られていても検索できるwhere節の作り方(全文検索を使わない)

Posted at

laravelで、DBのカラムがfirst_nameとlast_nameに分かれている。
しかし検索キーワードはいろんなパターンに対応させるように検索させたい場合。
でも全文検索は使えない。

そんな時に役立つかもしれない記事です。

DBの例

id last_name fist_name
1 山田 太郎
2 田中 花子

ユーザーからの検索クエリ

  1. 山田 太郎
  2. 山田太郎
  3. 山田
  4. 太郎

という感じで、どんなパターンでも検索をヒットさせたい。
でも全文検索は使わない場合は、このように書けば解決できます。

解決コードのEuloquent Where節部分です

前提
usersには検索したいEuloquentモデルが入っているものとします。
keywordsには検索クエリが入っているものとします。

$users->Where(function ($query) use ($keywords) {
     $splited_keywords = extractKeywords($keywords);
     foreach($splited_keywords as $keyword){
        $query->orWhere('last_name', 'LIKE', "%{$keyword}%")
              ->orWhere('first_name', 'LIKE', "%{$keyword}%")
              ->orWhereRaw('CONCAT(last_name, "", first_name) LIKE ? ', '%' . $keyword . '%');
      }
});

という感じで、送られてきたkeywordを空白文字列で分割しながら、各列を検索し、かつ、CONCATで結合したカラムを検索します。どれかにHITすればOK。

空白文字列が含まれる配列を分割するのはこちらの記事を参考にしました。
https://qiita.com/mpyw/items/a704cb900dfda0fc0331

function extractKeywords(string $input, int $limit = -1): array
    {
        return array_values(array_unique(preg_split('/[\p{Z}\p{Cc}]++/u', $input, $limit, PREG_SPLIT_NO_EMPTY)));
    }

この記事があなたの生産性を少しでも上げることができたならば
LGTMボタンお願いします!

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?