简体   繁体   English

Laravel 4和全文搜索

[英]Laravel 4 and full-text search

I have seen quite a few articles on fulltext search in Laravel where users recommend using whereRaw(...) or DB::query(...), but my aim is to remain database agnostic. 我在Laravel中看到了很多关于全文搜索的文章,用户建议使用whereRaw(...)或DB :: query(...),但是我的目标是保持数据库不可知。 I understand that a where('col', 'like', '%foo%') is terrible wrt performance. 我知道where('col','like','%foo%')是糟糕的wrt性能。

So I believe I am left with creating my own database index. 因此,我相信剩下的工作就是创建自己的数据库索引。 Is there something that I can do out of the box with Laravel, or some table structure that I can set up to build a faster search mechanism? 是否可以使用Laravel开箱即用,或者可以建立一些表结构来构建更快的搜索机制?

Currently, I have a 'main' table with a text column 'data' on which I am planning to run a search on. 目前,我有一个“主”表,其中有一个文本列“ data”,我打算在该表上进行搜索。 That is the only column on which I'm doing lookups. 那是我正在查找的唯一列。

if queries are not a problem, this is how I did it. 如果查询不是问题,这就是我的方法。

First, include the search form in your view: 首先,在您的视图中包括搜索表单:

{{ Form::open(['method' => 'get']) }}
{{ Form::text('q',Input::get('q')) }}
{{ Form::submit('Search') }}
{{ Form::close() }}

Make sure the table you want to search is MyISAM, you can do this by adding this to a migration: 确保要搜索的表是MyISAM,可以通过将其添加到迁移中来做到这一点:

$table->engine = 'MYISAM';

After that, add this scope to your model and change the columns you want to search: 之后,将此作用域添加到模型中并更改要搜索的列:

public function scopeSearch($query,$q) {
  return empty($q) ? $query : $query->whereRaw(
    "MATCH(title,contents,anotherfield) 
      AGAINST(? IN BOOLEAN MODE)",[$q]);
}

In your controller, just add the scope when fetching the data: 在您的控制器中,只需在获取数据时添加作用域即可:

$posts = Posts::search(Input::get('q'))->get();

And it should work. 它应该工作。 In case you need to add pagination, do something like this: 如果您需要添加分页,请执行以下操作:

$posts = Posts::search(Input::get('q'))->paginate(30);

And for showing the links in the view, use this code: 为了在视图中显示链接,请使用以下代码:

{{ $posts->appends(Input::except('page'))->links() }}

This will preserve all the GET params (including the query param) while paginating. 这将在分页时保留所有GET参数(包括查询参数)。

Here is a function i use for a simple full-text serach with laravel. 这是我用于使用laravel进行简单全文搜索的功能。 If you use mysql rememeber to set the engine to MyISAM on the table. 如果您使用mysql记忆体在表上将引擎设置为MyISAM。

I have this function in the model file so that i can call User::serachFilter('query'); 我在模型文件中有此功能,因此我可以调用User :: serachFilter('query'); from the controller. 从控制器。

public static function searchFilter($data, $pageLimit = '5')
    {
        $keyword = !is_array($data) ? array('+'.$data.'*') : $data;
        $matchArray = array('firstName', 'lastName', 'location', 'address');
        $columns = array();
        foreach($matchArray as $column)
        {
            $columns[] = $column;
        }
        $match = implode(',', $columns);
        $result =  self::whereRaw('MATCH('.$match.') AGAINST (? IN BOOLEAN MODE)', $keyword)
                    ->paginate($pageLimit);

        return $result;
    }

Edit: Since you diden't want to use whereRaw, test 编辑:由于您不想使用whereRaw,请进行测试

    $query = Input::get('search');
    $pageLimit = Input::get('page_limit');

    $search = DB::select("
        select *
        from users
        where match(id, name, email, username)
        against('+{$query}*' IN BOOLEAN MODE)
        limit {$pageLimit}
    ");

    return $search;

This has been removed from Laravel 4 but as I already said in another question, it can easily be re-implemented as described here: http://creative-punch.net/implementing-laravel-4-full-text-search/ 它已从Laravel 4中删除,但正如我在另一个问题中已经说过的那样,可以按照此处所述轻松地重新实现: http : //creative-punch.net/implementing-laravel-4-full-text-search/

Though the FULLTEXT index does not work everywhere 尽管FULLTEXT索引并非在所有地方都有效

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM