laravel Поиск несколько слов, разделенных пробелом
Я новичок в laravel query builder, я хочу искать несколько слов, введенных в поле ввода, например, если я набираю "Jhon doe", я хочу получить любой столбец, содержащий jhon или doe
Я видел / пробовал решения с использованием php MySQL, но не могу адаптироваться к Query builder
//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 ";
}
как это сделать с помощью Query builder
это то, что у меня есть до сих пор, каков правильный способ сделать это,
$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.'%')
пожалуйста, помогите, спасибо заранее
7 ответов
вот как вы это делаете с 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);
Это будет работать.where будет искать имя из ключевых слов, которые вы ввели.
попробуйте это..
$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);
вы использовать полнотекстовый индекс на столбце "имя"?
вы можете создать этот индекс с помощью миграции 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"; обратите внимание, что этот подход будет соответствовать целым словам, а не подстрокам (что может быть, если вы используете ЛЮБИТЬ.)
если вы хотите найти записи, содержащие все слова, вы должны предшествовать каждому ключевому слову с"+", как это:
$keywords = '+'.explode(' +', $keywordRaw);
вы даже можете сортировать по релевантности, хотя это, вероятно, излишне для ваших нужд (и не имеет значения для "всех" поисков). Что-то вроде этого:--5-->
$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
вы можете использовать этот пакет https://github.com/nicolaslopezj/searchable
или просто сделайте это, если вы не хотите использовать package
$keywordRaw = "jhon doe";
$users = User::where('first_name', 'LIKE', $keywordRaw.'%')
->orWhere('first_name', 'LIKE', '% '.$keywordRaw.'%')
->get();
$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->Where('name', 'like', "%{$value}%");
}
})->get();
использование "orWhere" даст вам результаты для каждого ключевого слова, а не результаты для keyword1 + keyword2...поэтому все зависит от того, что вы ищете