Laravel 4 和全文搜索

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20210804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 08:42:05  来源:igfitidea点击:

Laravel 4 and full-text search

phpsqlsearchlaravel

提问by Sayak Banerjee

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. I understand that a where('col', 'like', '%foo%') is terrible w.r.t. performance.

我在 Laravel 中看到了很多关于全文搜索的文章,用户推荐使用 whereRaw(...) 或 DB::query(...),但我的目标是保持数据库不可知。我知道 where('col', 'like', '%foo%') 的性能很差。

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. That is the only column on which I'm doing lookups.

目前,我有一个“主”表,其中有一个文本列“数据”,我打算在该表上运行搜索。这是我进行查找的唯一列。

回答by Arne

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 参数(包括查询参数)。

回答by oBo

Here is a function i use for a simple full-text serach with laravel. If you use mysql rememeber to set the engine to MyISAM on the table.

这是我用于使用 laravel 进行简单全文检索的函数。如果使用mysql rememeber 将引擎设置为MyISAM 就可以了。

I have this function in the model file so that i can call User::serachFilter('query'); from the controller.

我在模型文件中有这个函数,这样我就可以调用 User::serachFilter('query'); 从控制器。

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;

回答by KennyV

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 索引在任何地方都不起作用