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
Laravel 4 and full-text search
提问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 索引在任何地方都不起作用