Laravel - Полный поиск текста в нескольких таблицах

Я использую Laravel 4 и модель Eloquent для проекта, над которым мы работаем. База данных соответствует 3NF, и все работает отлично. Также все MySQL-таблицы были переведены обратно из InnoDB в MyISAM, поскольку версия MySQL < 5.6 (полнотекстовый поиск в InnoDB поддерживается только с 5.6 и выше).

При создании некоторых фильтров поиска базы данных я нахожу нехватку с использованием модели Eloquent и Query Builder. В особенности, особенно при попытке выполнить полный текстовый поиск по столбцам из нескольких таблиц (и оставаться в контексте объекта 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.name, projects.description и notes.note. Когда вы пытаетесь найти, как сделать это с помощью Eloquent, мы продолжаем возвращаться к Query Builder и запускаем пользовательский запрос, который будет работать нормально, но тогда мы столкнемся с этими проблемами/минусами:

  • Query Builder возвращает массив, а Eloquent возвращает объекты модели. Поскольку мы расширяем каждую модель, чтобы включить методы, мы действительно не хотим отказываться от удивительности модели Eloquent. И мы действительно не хотим использовать Eloquent Project::find($id) для результатов возврата только для того, чтобы снова получить объект.
  • Мы объединяем методы "where", чтобы иметь любое количество фильтров назначенные ему, а также для повторного использования кода. Кажется, Выражение "Красноречивый" и "Query Builder" вместе разрушит нашу цепочку.
  • Для согласованности этого проекта мы хотим, чтобы все запросы к базе данных оставаться в значении "Красноречивый".

Чтение документации Laravel и API, я не мог найти способ запуска сырых SQL-запросов с использованием Eloquent. Существует whereRAW(), но оно недостаточно широкое. Я предполагаю, что это ограничение сделано по дизайну, но это все еще ограничение.

Итак, мои вопросы:

  • Возможно ли выполнить полнотекстовый поиск по столбцам из нескольких таблиц, только в Eloquent. Каждый фрагмент информации, с которой я столкнулся в Интернете, упоминается в Query Builder.
  • Если нет, можно ли использовать поисковые запросы Query Builder и возвращать объекты Eloquent? (без необходимости запускать Project::find($id) в результатах массива).
  • И, наконец, можно ли объединить методы Eloquent и Query Builder where вместе, а только совершая использование get() или paginate(10) в более поздней точке.

Я понимаю, что Eloquent и Query Builder - это разные существа. Но если смешение обоих было возможно или использование Eloquent для запуска сырых SQL-запросов, я считаю, что модель Eloquent станет намного более надежной. Использование только Query Builder мне кажется немного неэффективным с использованием рамки Laravel.

Надеюсь получить некоторые сведения об этом, поскольку кажется, что форумы/сообщество Laravel все еще развиваются, хотя я считаю, что это потрясающая структура!

Спасибо, и я ценю любой вход, который у вас может быть:)

2 ответа

Прежде всего, вы можете использовать область запроса в своей модели /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();

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


Не уверен, что это поможет, но в 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(?)

licensed under cc by-sa 3.0 with attribution.