Я новичок в laravel query builder, я хочу искать несколько слов, введенных в поле ввода, например, если я нахожу «jhon doe», я хочу получить любой столбец, содержащий jhon или doe
Я видел / пытался решения с использованием php MySQL, но не смог адаптироваться к построителю запросов
//1. exploding the space between the keywords //2. using foreach apend the query together $query = "select * from users where"; $keywordRaw = "jhon doe"; $keywords = explode(' ', $keywordRaw ); foreach ($keywords as $keyword){ $query.= " first_name LIKE '%" + $keyword +"%' OR "; }
как это сделать, используя построитель запросов
это то, что у меня есть до сих пор, каков правильный способ сделать это,
$keywordRaw = "jhon doe"; //how do I explode this words and append them along with their appropriate query $users = User::select('users.*') ->where('first_name', 'LIKE', '%'.$keywordRaw.'%')
пожалуйста, помогите, спасибо заранее
Так вы делаете это с Query\Builder
, но сначала добавьте несколько примечаний:
// user can provide double space by accident, or on purpose: $string = 'john doe'; // so with explode you get this: explode(' ', $string); array( 0 => 'john', 1 => '', 2 => 'doe' ) // Now if you go with LIKE '%'.value.'%', you get this: select * from table where name like '%john%' or name like '%%' or ...
Тем не менее, вы, очевидно, не можете полагаться на explode
потому что в приведенном выше случае вы получите все строки.
Итак, это то, что вы должны делать:
$string = 'john doe'; // split on 1+ whitespace & ignore empty (eg. trailing space) $searchValues = preg_split('/\s+/', $string, -1, PREG_SPLIT_NO_EMPTY); $users = User::where(function ($q) use ($searchValues) { foreach ($searchValues as $value) { $q->orWhere('name', 'like', "%{$value}%"); } })->get();
Существует замыкание в том, where
потому что это хорошая практика для того, чтобы обернуть ваши предложения or where
предложения в круглых скобках. Например, если ваша модель User
использовала SoftDeletingScope
и вы не сделали бы того, что я предложил, весь ваш запрос был бы испорчен.
$keywordRaw = "jhon doe"; $key = explode(' ',$keywordRaw) $users = User::select('users.*') ->whereIn('first_name',$key);
Это будет работать. WhereIn будет искать первое имя из введенных вами ключевых слов.
Попробуй это..
$searchQuery = "jhon doe"; $searchTerms = explode(" ", $searchQuery); // Split the words $users = User::whereIn('FirstName', $searchTerms)->get(); print_r($users);
Вы можете попробовать следующее
$keywordRaw = "jhon doe"; $bindArr = explode(" ", $keywordRaw); $query = "select * from users where"; foreach ($i = 0; $i < count($bindArr); $i++) { if ($i == 0) { $query.= ' first_name LIKE "%?%"'; } else { $query.= ' or first_name LIKE "%?%"'; } } $sth = $dbh->prepare($query); $sth->execute($bindArr);
Считаете ли вы использование индекса FULLTEXT в столбце first_name?
Вы можете создать этот индекс, используя миграцию Laravel, хотя вам нужно использовать инструкцию SQL:
DB::statement('ALTER TABLE users ADD FULLTEXT(first_name);');
Затем вы можете запустить довольно продвинутый поиск по этому полю, например:
$keywordRaw = "john doe"; $keywords = explode(' ', $keywordRaw); $users = User::select("*") ->whereRaw("MATCH (first_name) against (? in boolean mode)",[$keywords]) ->get();
Это будет соответствовать записям, содержащим слова «john» или «doe»; обратите внимание, что этот подход будет соответствовать целым словам, а не подстрокам (что может иметь место, если вы используете LIKE).
Если вы хотите найти записи, содержащие все слова, перед каждым ключевым словом должно быть указано «+», например:
$keywords = '+'.explode(' +', $keywordRaw);
Вы даже можете сортировать по релевантности, хотя это, вероятно, слишком велико для ваших нужд (и не имеет значения для «всех» поисков). Что-то вроде этого:
$users = User::select("*") ->selectRaw("MATCH (first_name) against (? in boolean mode) AS relevance",[$keywords]) ->whereRaw("MATCH (first_name) against (? in boolean mode)",[$keywords]) ->orderBy('relevance','DESC') ->get();
Существует хорошая статья, которая охватывает этот общий подход здесь:
http://www.hackingwithphp.com/9/3/18/advanced-text-searching-using-full-text-indexes