2014-02-19 39 views
3

我正在使用Laravel 4和Eloquent模型來開展我們正在進行的項目。 數據庫符合3NF,一切都很好。由於MySQL版本< 5.6(InnoDB中的全文搜索僅支持5.6及更高版本),因此所有MySQL表都從InnoDB切換回MyISAM。Laravel - 在多個表格上進行全文搜索

在創建一些數據庫搜索過濾器時,我發現使用Eloquent模型與查詢生成器有些不足。具體來說,特別是當試圖對來自多個表的列進行全文搜索時(並且保留在Eloquent的對象上下文中)。

爲簡單起見,我們有以下的數據庫結構:

--projects 
    --id 
    --name 
    --status 
    --... 
--users 
    --id 
    --... 
--roles 
    --id 
    --project_id 
    --user_id 
    --... 
--notes 
    --id 
    --project_id 
    --user_id 
    --note 
    --.... 

下面的代碼(簡體和最小化的問題)目前工作正常,全文搜索只適用於一個表(projects表)。

if (Request::isMethod('post')) 
     { 

       $filters = array('type_id','status','division','date_of_activation','date_of_closure'); 

       foreach ($filters as $filter) { 
        $value = Input::get($filter); 
        if (!empty($value) && $value != -1) {//-1 is the value of 'ALL' option 
         $projects->where($filter,'=',$value); 
        } 
       } 

       $search = Input::get('search'); 

       if (!empty($search)) { 
        $projects->whereRAW("MATCH(name,description) AGAINST(? IN BOOLEAN MODE)",array($search)); 
       } 

     } 


// more code here... 
// some more filters... 
// and at the end I am committing the search by using paginate(10) 

return View::make('pages/projects/listView', 
      array(
      "projects" => $projects->paginate(10) 
      ) 
     ); 

我需要延長全文搜索包括以下幾列 - projects.nameprojects.descriptionnotes.note。 當試圖找到如何與口才讓我們繼續回來到查詢生成器,並運行自定義查詢,這將很好地工作,但接下來我們將面對這些問題/缺點:

  1. 查詢生成器返回一個數組而Eloquent返回模型對象。由於我們正在擴展每個模型以包含方法,所以我們不希望放棄Eloquent模型的可怕性。我們真的不想在返回結果上使用Eloquent Project::find($id)來再次獲取對象。
  2. 我們正在鏈接'where'方法,爲其分配任意數量的過濾器 以及代碼重用性。似乎混合 雄辯和查詢生成器語句一起將打破我們的鏈接。
  3. 爲了保證項目的一致性,我們希望所有的數據庫查詢都以 保留在Eloquent內涵中。

閱讀Laravel的文檔和API,我找不到使用Eloquent運行原始SQL查詢的方法。有whereRAW()但它不夠廣泛。我認爲這是設計限制,但它仍然是一個限制。

所以我的問題是:

  1. 是否有可能運行在從多個表列的全文搜索,只在侃侃而談。我在網上遇到的每一條信息都使用了查詢生成器。
  2. 如果沒有,是否可以使用查詢生成器搜索並返回Eloquent對象? (無需在陣列結果上運行Project::find($id))。
  3. 最後,是否可以將Eloquent和Query Builder where方法鏈接在一起,而僅在稍後使用get()paginate(10)時才提交。

我明白,雄辯和查詢生成器是不同的生物。但是,如果混合兩者都是可能的,或者使用Eloquent運行原始SQL查詢,我相信Eloquent模型將變得更加健壯。只使用查詢生成器在我看來有點像在使用Laravel框架。

希望得到一些關於這方面的見解,因爲它看起來Laravel的論壇/社區仍在不斷髮展,儘管我發現它是一個了不起的框架!

謝謝,我明白任何輸入你可能有:)

如果
+0

你能解決嗎? –

回答

1

不知道這將有助於但在InnoDB的解決方法(在支持全文檢索的版本),也許是你的作品。
允許使用 '註釋' 作爲第二表

SELECT MATCH(name,description) AGAINST(? IN BOOLEAN MODE), 
     MATCH(notes.note) AGAINST(? IN BOOLEAN MODE) 
FROM ... 

WHERE 
MATCH(name,description) AGAINST(?) OR 
MATCH(notes.note) AGAINST(?) 
+0

謝謝,但這是一個原始SQL,Laravel的雄辯不允許原始SQL(AFAIK)。我將不得不使用查詢生成器,但這是我從第一個地方提問的原因:)它也使用Active Record,所以我相信它禁止我在外表列上運行匹配項... – Yani

4

首先,你可以使用查詢範圍在模型/ s的

public function scopeSearch($query, $q) 
{   
    $match = "MATCH(`name`, `description`) AGAINST (?)"; 
    return $query->whereRaw($match, array($q)) 
       ->orderByRaw($match.' DESC', array($q)); 
} 

這樣你可以得到「雄辯集」作爲回報

$projects = Project::search(Input::get('search'))->get(); 

然後,還搜索到筆記中,您可以創建一個更復雜的範圍,以便在那裏加入筆記和搜索。