2014-02-19 2 views
3

우리가 작업중인 프로젝트에 Laravel 4와 Eloquent 모델을 사용하고 있습니다. 데이터베이스가 3NF를 준수하며 모든 것이 훌륭하게 작동합니다. 또한 모든 MySQL 테이블은 MySQL 버전 < 5.6 (InnoDB의 전체 텍스트 검색은 5.6 이상에서만 지원됩니다) 이후 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 표). projects.name, projects.descriptionnotes.note -

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

나는 다음과 같은 열을 포함하는 전체 텍스트 검색을 확장 할 필요가있다. 우리가 Builder를 쿼리로 돌아오고 잘 작동하는 사용자 지정 쿼리를 실행 계속 웅변으로 만드는 방법을 찾기 위해 노력하지만 우리가 직면하게 될 것이다 이러한 문제/단점 :

  1. 쿼리 빌더는 배열을 반환 Eloquent는 모델 객체를 반환합니다. 메소드를 포함하도록 각 모델을 확장하고 있기 때문에, 우리는 Eloquent 모델의 awesomeness를 포기하고 싶지 않습니다. 그리고 우리는 실제로 객체를 다시 얻으려면 결과 값에 Eloquent Project::find($id)을 사용하고 싶지 않습니다.
  2. 우리는 '어디에'메서드를 연결하여 코드 재사용을 위해뿐만 아니라 필터도 할당 할 수 있습니다. Eloquent와 Query Builder 문을 함께 사용하면 체인이 끊어집니다.
  3. 이 프로젝트의 일관성을 위해 에 대한 모든 데이터베이스 쿼리가 Eloquent connotation으로 유지되기를 바랍니다.

Laravel의 설명서와 API를 읽고 Eloquent를 사용하여 원시 SQL 쿼리를 실행하는 방법을 찾을 수 없습니다. whereRAW()이 있지만 충분히 넓지는 않습니다. 나는 이것이 디자인에 의해 만들어진 제한이라고 생각하지만 여전히 제한이다.

그래서 제 질문은 다음과 같습니다

  1. 하는 것이 가능에만 웅변에 여러 테이블의 열에서 전체 텍스트 검색을 실행하는 것입니다. 온라인에서 발견 한 모든 정보는 Query Builder를 사용하여 언급됩니다.
  2. 그렇지 않은 경우 쿼리 작성기를 사용하여 Eloquent 개체를 검색하고 반환 할 수 있습니까? (배열 결과에 Project::find($id)을 실행할 필요없이).
  3. 마지막으로 where 메서드를 함께 묶어 나중에 get() 또는 paginate(10)을 사용하여 커밋 할 수 있습니까?

나는 Eloquent와 Query Builder가 다른 생물임을 이해합니다.그러나 둘 모두를 혼합하거나 원시 SQL 쿼리를 실행하는 데 Eloquent를 사용하면 Eloquent 모델이 훨씬 더 강력해질 것이라고 믿습니다. Query Builder 만 사용하면 Laravel 프레임 워크를 과소 평가하는 것처럼 보입니다.

Laravel의 포럼/커뮤니티가 여전히 놀라운 프레임 워크로 자리 매김하고 있음에도 불구하고이 포럼에 대한 통찰력을 얻기를 바랍니다.

덕분에 나는 아마도 당신을 위해 작동, 당신은 할 수 있습니다 :)이 도움이 될 것입니다하지만 (전체 텍스트 검색을 지원하는 버전) 이노 디비에 해결 방법이

+0

해결할 수 있습니까? –

답변

1

확실하지 경우 모든 입력을 주셔서 감사합니다.
는 두 번째 테이블

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의 Eloquent는 원시 SQL (AFAIK)을 허용하지 않습니다. 나는 그것을 위해 쿼리 빌더를 사용해야 할 것이다. 그러나 그것은 내가 처음부터 질문을 던지고있는 이유 다. :) 또한 액티브 레코드를 사용하여 내가 외국 테이블 컬럼에서 일치를 실행하는 것을 금지한다고 믿는다. – 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(); 

후 복귀로 "웅변 모음"을 얻을 수 있습니다 이런 식으로 쿼리 범위를 사용할 수 있습니다, 또한 검색하기 메모에 합류하고 검색 할 수있는 더 복잡한 범위를 만들 수 있습니다.