web-dev-qa-db-ja.com

Laravel-値に特定の文字列が含まれている場合のクエリモデル(検索入力から取得)

LaravelとAjaxを使用して検索を実装しています。そのため、タグとサブカテゴリに属している製品があります。一方、サブカテゴリはカテゴリに属しています。すべてのそれらのプロパティ(フィールド値)をチェックし、指定された文字列が含まれているかどうかを確認します。検索の結果、LIKEを使用する必要があることがわかりました。

$products = Product::where('name_en', 'LIKE', $search)->get();

ただし、検索文字列が値と完全に一致する場合は、商品が取得されます。それが含まれている場合、私は一致させたいです。 belongsToの関係をどのように進めることができますか?タグとサブカテゴリのプロパティも確認するにはどうすればよいですか?すべてを連鎖させて目的の結果を得るにはどうすればよいですか?前もって感謝します。

5
Codearts

あなたは一つ間違ったことをしている、あなたは正確な文字列を与えたのであなたのクエリはあなたに完全に一致するものを返す。しかし、クエリは次のようになります。

_$products = Product::where('name_en', 'LIKE', '%'.$search.'%')->get();
_

上記のクエリは、検索された文字列を含む製品を提供します。

リレーショナルテーブルで検索する場合は、laravel method join()を使用できます。ただし、もう1つのメソッドwhereHasがありますが、この方法は常に避けています。 、それは非常に複雑なクエリを作成するためです。これは非常に重いので、リレーショナルテーブルで_inner join_を追加するjoin()メソッドを使用できます。

次に、結合の例を示します。

_$products = Product::join('tags', function($builder) {
                        $builder->on('tags.id', '=', 'products.tag_id');
                        // here you can add more conditions on tags table.
                    })
                    join('sub_categories', function($builder) {
                        $builder->on('sub_categories.id', '=', 'products.tag_id');
                        // here you can add more conditions on subcategories table.
                    })
                    ->where('name_en', 'LIKE', '%'.$search.'%')
                    ->get();
_

これは基本的な例であり、要件に応じて使用できます。

25
user2754452

Lakhwinder Singh の答えに追加するには、モデルに適用できるスコープにまとめる価値があるかもしれません。

class Product extends Model
{
    public function scopeSearch($query, $keywords)
    {
        return $query->where('name_en', 'LIKE', '%'.$keywords.'%');
    }
}

次に、このスコープを次のように使用できます。

$products = Product::search($keywords)->get();

つまり、アプリケーション全体に「LIKE」条件を手動で追加し続ける必要はありません。

ちなみに、Laravelのバージョン5.3では、Eloquentのドライバーベースの全文検索拡張機能であるScoutが紹介されています。

8
Martin Bean

必要なのは、関連するモデルに基づいて製品を検索するための高度なクエリを作成することです。そのため、他の人からの以前の提案と同様に、結合ステートメントを作成する必要があります。

メンバーを検索するために記述された以下の私のサンプルコードを確認してください。文字列が一致する場合、メンバーのスキルや位置が検索文字列にもメンバーをもたらすため、これは確実に役立ちます。

$users = User::select('app_users.*')
            ->distinct()
            ->join('app_members', 'app_users.id', '=', 'app_members.app_users_id')
            ->leftJoin('app_members_jobtitles', 'app_members.id', '=', 'app_members_jobtitles.app_members_id')
            ->leftJoin('app_jobtitles', 'app_members_jobtitles.app_jobtitles_id', '=', 'app_jobtitles.id')

            ->leftJoin('app_members_tags', 'app_members.id', '=', 'app_members_tags.app_members_id')
            ->leftJoin('app_technologies', 'app_members_tags.app_technologies_id', '=', 'app_technologies.id')
            ->whereNull('app_users.activation')
            ->where('app_users.block','=',0)
            ->where(function ($query)use ($search) {
                $query->orWhere('app_users.first_name', 'like', '%'.$search.'%')
                      ->orWhere('app_users.last_name', 'like', '%'.$search.'%')
                      ->orWhere('app_members.company', 'like', '%'.$search.'%')
                      ->orWhere('app_members.job_title', 'like', '%'.$search.'%')
                      ->orWhere('app_jobtitles.title', 'like', '%'.$search.'%')
                      ->orWhere('app_technologies.title', 'like', '%'.$search.'%')
                      ->orWhere('app_members.summary', 'like', '%'.$search.'%');
            })
            ->get();

上記のコードの次の結合に注意してください。これは、ケースカテゴリとサブカテゴリにあります。

->leftJoin('app_members_jobtitles', 'app_members.id', '=', 'app_members_jobtitles.app_members_id')
        ->leftJoin('app_jobtitles', 'app_members_jobtitles.app_jobtitles_id', '=', 'app_jobtitles.id')
1
Akram Wahid