2013-11-26 112 views
1

我已經看到了不少關於Laravel全文搜索的文章,其中用戶推薦使用whereRaw(...)或DB :: query(...),但我的目標是保持數據庫不可知。我明白,一個where('col','like','%foo%')是可怕的w.r.t.性能。Laravel 4和全文搜索

所以我相信我留下來創建我自己的數據庫索引。 Laravel有沒有什麼可以做的,或者我可以設置一些表結構來建立更快的搜索機制?

目前,我有一個'主'表,上面有一個文本列'data',我打算在其上運行搜索。這是我在查找的唯一一列。

+1

長(但更好)的道路將使用Lucene(來自Zend的PHP實現:http://framework.zend.com/manual/1.12/en/zend.search.lucene.html)等搜索引擎。 –

回答

1

這是一個函數,我用一個簡單的全文serach與laravel。 如果您使用mysql記事在引擎上將引擎設置爲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; 
    } 

編輯: 既然你diden't要使用

$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; 
+0

感謝您的回答,但是,我想避免使用whereRaw,因爲它並不真正構建基於底層數據庫引擎的查詢。 –

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]); 
} 

I在您的控制器中,只需在獲取數據時添加示波器:

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

它應該可以工作。如果您需要添加分頁,做這樣的事情:

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

而對於顯示在視圖中的鏈接,使用此代碼:

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

這樣會保留所有的GET PARAMS(包括查詢參數),而分頁。