我在Laravel上看过很多关于全文搜索的文章,用户建议使用whereRaw(...)或DB :: query(...),但我的目标是保持数据库不可知。我明白一个地方('col','like','%foo%')是可怕的w.r.t.性能
所以我相信我只剩下创建自己的数据库索引了。有什么东西我可以用Laravel开箱即用,或者我可以设置一些表结构来构建更快的搜索机制吗?
目前,我有一个'主'表,其中包含一个文本列'data',我打算在其上运行搜索。这是我正在查找的唯一列。
答案 0 :(得分:5)
如果查询不是问题,我就是这样做的。
首先,在您的视图中包含搜索表单:
{{ Form::open(['method' => 'get']) }}
{{ Form::text('q',Input::get('q')) }}
{{ Form::submit('Search') }}
{{ Form::close() }}
确保您要搜索的表格是MyISAM,您可以通过将其添加到迁移中来执行此操作:
$table->engine = 'MYISAM';
之后,将此范围添加到模型中并更改要搜索的列:
public function scopeSearch($query,$q) {
return empty($q) ? $query : $query->whereRaw(
"MATCH(title,contents,anotherfield)
AGAINST(? IN BOOLEAN MODE)",[$q]);
}
在您的控制器中,只需在获取数据时添加范围:
$posts = Posts::search(Input::get('q'))->get();
它应该有效。如果您需要添加分页,请执行以下操作:
$posts = Posts::search(Input::get('q'))->paginate(30);
要显示视图中的链接,请使用以下代码:
{{ $posts->appends(Input::except('page'))->links() }}
这将在分页时保留所有GET参数(包括查询参数)。
答案 1 :(得分:1)
这是一个我用于简单的全文serach与laravel的功能。 如果你使用mysql rememeber在桌面上将引擎设置为MyISAM。
我在模型文件中有这个功能,所以我可以调用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;
}
编辑: 既然你想要使用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;
答案 2 :(得分:1)
这已从Laravel 4中移除,但正如我在另一个问题中已经说过的那样,它可以很容易地重新实现,如下所述:http://creative-punch.net/implementing-laravel-4-full-text-search/
虽然FULLTEXT索引无处不在