laravel搜索由空格分隔的多个单词

时间:2015-02-02 02:12:59

标签: php mysql laravel eloquent query-builder

我是laravel查询构建器的新手,我想搜索在输入字段中输入的多个单词,例如,如果我输入" 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.'%')

请提前帮助,请提供帮助

8 个答案:

答案 0 :(得分:26)

这是你使用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并且您不会按照我的建议行事,那么您的整个查询就会搞砸。

答案 1 :(得分:3)

 $keywordRaw = "jhon doe";
    $key = explode(' ',$keywordRaw)
    $users = User::select('users.*')
    ->whereIn('first_name',$key);

这样可行.theIn将从您输入的关键字中搜索名字。

答案 2 :(得分:2)

试试这个..

   $searchQuery = "jhon doe"; 
$searchTerms = explode(" ", $searchQuery); // Split the words
$users = User::whereIn('FirstName', $searchTerms)->get();
print_r($users);

答案 3 :(得分:1)

您可以尝试以下

$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);

答案 4 :(得分:1)

您是否考虑在first_name列上使用FULLTEXT索引?

您可以使用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();

这将匹配包含单词&#34; john&#34;或&#34; doe&#34 ;;请注意,此方法将匹配整个单词,而不是子字符串(如果您使用LIKE,则可能就是这种情况)。

如果您要查找包含所有字词的记录,则应在每个关键字前加上&#39; +&#39;,如下所示:

$keywords   = '+'.explode(' +', $keywordRaw);

您甚至可以根据相关性进行排序,尽管这可能对您的需求有些过分(与#34;所有&#34;搜索无关)。像这样:

$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

答案 5 :(得分:0)

您可以使用此资料包https://github.com/nicolaslopezj/searchable

或者只是这样做,如果你不想使用包

$keywordRaw = "jhon doe";
$users = User::where('first_name', 'LIKE', $keywordRaw.'%')
->orWhere('first_name', 'LIKE', '% '.$keywordRaw.'%')
->get();

答案 6 :(得分:0)

$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();

使用“或在哪里”将为您获得每个关键字的结果,而不是关键字1 +关键字2的结果...所以一切都取决于您要寻找的东西

答案 7 :(得分:0)

我在下面写了第一个解决方案,它奏效了

解决方案 1

function fuzzySearch($keyword='jhon doe'){
   $queryText = implode('%',str_split($keyWord));
   return User::query()->where('first_name','LIKE',"%{$queryText}%")->get();
}

但是,当我在搜索中添加空格时,它返回空结果,但它们存在于数据库中,所以我添加了 str_replace(" ","",$keyWord) 来删除空格,现在它可以工作了

解决方案 2

function fuzzySearch($keyword='jhon doe'){
   $queryText = implode('%',str_split(str_replace(" ","",$keyWord)));
   return User::query()->where('first_name','LIKE',"%{$queryText}%")->get();
}

注意 implode() 函数将关键字 jhon doe 转换为 j%h%o%n%d%o%e