2015-02-12 6 views
2

Я пытаюсь реализовать полнотекстовый поиск в базе данных. Это в спецификации, что мой клиент послал меня:Laravel полный текстовый поиск

"The free text search limits the result of the data table to records with a matching first 
name, last name, country, city, state, or zip code. If several words are input, 
each word must match one of the columns for a record to be visible." 

Я сделал некоторые очень уродливый код спагетти в моем контроллере, чтобы попытаться, если он работает:

public function search($searchTerms){ 
     $searchTerms = explode(' ', $searchTerms); 
     $results = array(); 
     foreach ($searchTerms as $searchTerm) { 
      if (!People::where('firstname', 'LIKE', '%'.$searchTerm.'%')->get()->isEmpty()) { 
       array_push($results, People::where('firstname', 'LIKE', '%'.$searchTerm.'%')->get()); 
      } 
      else if (!People::where('lastname', 'LIKE', '%'.$searchTerm.'%')->get()->isEmpty()) { 
       array_push($results, People::where('lastname', 'LIKE', '%'.$searchTerm.'%')->get()); 
      } 
     } 
     return $results; 
    } 

И это мой призыв к этому функция:

$data->people = $this->search(Input::get('search')); 

проблема заключается в том, что если нет поиска входа, я использую это, чтобы получить все данные:

$data->people = People::orderBy($order)->paginate(10); 

И, получив результаты поиска в виде массива, я получаю следующее сообщение об ошибке в моих просмотров:

Undefined property: Illuminate\Database\Eloquent\Collection::$firstname (View: /home/projects/pplproject/app/views/index.blade.php) 

Как это должно быть реализовано в Laravel образом?

+0

ли «свободный текст» должен быть «полный текст»? Хотя небольшое изменение, вы, скорее всего, получите результаты поиска, используя «полный текст». Я не пытаюсь быть nitpicky. –

+0

Я считаю, что это должен быть полный текст. Не знал, что это называется, спасибо за головы! :) – Peter

ответ

6

В принципе, целью здесь должно быть выполнение всего этого в одном запросе. Здесь идет:

$searchTerms = explode(' ', $searchTerms); 
$query = People::query(); 

foreach($searchTerms as $searchTerm){ 
    $query->where(function($q) use ($searchTerm){ 
     $q->where('firstname', 'like', '%'.$searchTerm.'%') 
     ->orWhere('lastname', 'like', '%'.$searchTerm.'%') 
     ->orWhere('country', 'like', '%'.$searchTerm.'%') 
     // and so on 
    }); 
} 

$results = $query->get(); 

Для родственных моделей вы можете попробовать что-то вроде этого:

foreach($searchTerms as $searchTerm){ 
    $query->where(function($q) use ($searchTerm){ 
     $q->where('firstname', 'like', '%'.$searchTerm.'%') 
     ->orWhereHas('relationName', function($relation) use ($searchTerm){ 
      $relation->where('relation_attribute', 'like', '%'.$searchTerm.'%'); 
     }); 
    }); 
} 
+0

Спасибо, отлично работает! У меня также есть 2 столбца в моей базе данных, которые имеют внешние ключи. Как ваш ответ может быть изменен, чтобы иметь возможность искать их по имени? – Peter

+0

Добро пожаловать. Взгляните на обновленный ответ. Надеюсь, что это поможет;) – lukasgeiter

+0

Другое дело: можно ли упорядочить результаты с помощью 'orderBy()'? Я попытался вызвать его после последнего «или где-то» и на модели («Люди :: orderby (« firstname ») -> query()'), но он, похоже, не работает. – Peter

Смежные вопросы