Компонент FTSearch: поисковая система
Компонент FTSearch представляет собой поисковую систему, построенную на использовании полнотекстового поиска, предоставляемого средствами MySQL. Это простейший вариант реализации алгоритма поиска. Поэтому, если для сайта требуется более продвинутые алгоритмы поиска, то такой вариант не подойдет и лучше прибегнуть к другому решению.
Компонент обеспечивает основные возможности, которые обычно требуются от поисковой системы:
- Индексация как отдельных документов, так и всего сайта целиком.
- Поддержка русской морфологии (использование Lingua.Stem.Ru).
- Некоторый язык запросов, соответствующий языку полнотекстовых запросов MySQL.
- Построение поисковых сниппетов на странице результатов поиска с подсветкой найденных слов.
- Ведение лога поисковых запросов.
Для работы компонента не требуется специальной настройки. После установки компонента и вывода формы поиска потребуется лишь переиндексировать сайт для первоначального формирования индекса. Функция переиндексации доступна в административной части сайта, как и список проиндексированных страниц. Если установлен компонент Nodus, то методы сбора и передачи материалов в индекс в нем уже настроен. Поэтому определение дополнительных методов не понадобится.
Особенность данной поисковой системы заключается в том, что индексация самих документов в нем не производится. Если требуется, чтобы документы того или иного компонента участвовали в поиске, то следует самостоятельно доработать компонент так, чтобы он мог добавлять свои документы в индекс поисковой системы.
Существует два режима работы: индексация отдельных документов и полная переиндексация.
Индексация отдельных документов
Позволяет организовать автоматическую регистрацию документов в индексе («на лету»), не прибегая к переиндексации всего сайта, т.е. всегда поддерживать в актуальном состоянии индекс поисковой системы.
Предположим есть простой компонент, обеспечивающий элементарное администрирование таблицы записей и их отображение на сайте. Необходимо организовать поиск записей этого компонента на сайте. Для этого необходимо реализовать следующие действия:
- При добавлении новости добавить запись в индекс.
- При удалении новости удалить соответствующую ей запись из индекса.
- При изменении новости удалить старую запись и добавить обновленную.
Прежде всего необходимо обратить внимание на идентификацию документа в индексе. Каждый документ идентифицируется двумя атрибутами:
- Имя компонента. Оно не обязательно должно иметь то же самое написание как имя каталога компонента. Оно вообще может быть совершенно другим. Но у каждого компонента в поиске оно должно быть уникальной строкой. Например, для нашего компонента Notes оно будет идентифицироваться как notes.
- Идентификатор документа в компоненте. Он может быть как числовым, так и буквенным. Но лучше всего для этого использовать числовой идентификатор записи (PRIMARY KEY). В нашем случае будем использовать значение поля id в таблице notes.
Теперь необходимо организовать работу с индексом. При использовании контроллера табличного администрирования можно воспользоваться услугами методов-событий:
//components/Notes/app/Admin.php // Этот метод вызывается при добавлении материала и изменении уже существующей. class Component_Notes_Admin extends CMS_Controller_Table { ... protected function on_after_change_item($item) { // Удалим старую запись. Если такой записи нет - ошибки не произойдет. CMS::objects()->indexer->delete_document('notes',$item->id); // Добавим новую/обновленную запись CMS::objects()->indexer->add_document('notes', $item->id, $item->title, $this->view_url($item), $item->content); } // Этот метод вызывается при удалении новости protected function on_after_delete_item($id) { // При удалении новости удалим соответствующую ей запись в индексе CMS::objects()->indexer->delete_document('notes', $id); } ... }
Для добавления документа в индекс следует передать следующую информацию:
- Имя компонента - хозяина документа.
- Внутренний идентификатор документа в компоненте.
- Название документа (будет показано на странице результатов поиска).
- URL документа.
- Тело документа. Можно передавать вместе с HTML-тегами - они будут автоматически вырезаны.
- Код подсайта (необязательный параметр) - для многосайтовых/многоязычных конфигураций.
Т.е., при добавлении нового материала, он автоматически будет попадать в индекс и, соответственно, при удалении материала, будет удален и из индекса. Без полной переиндексации данный материал будет доступен в выдаче поиска по сайту.
Полная переиндексация сайта
Требуется, когда необходима полная переиндексация материалов компонентов. Например, когда уже имеется ряд материалов и требуется добавить их в индекс.
При полной переиндексации сайта компоненту необходимо сначала удалить из индекса все свои записи, после чего добавить их заново. Команду на переиндексацию каждому компоненту дает поисковая система, для чего каждый компонент, участвующий в поиске, должен зарегистрироваться в поисковой системе.
Переиндексирующий метод
Прежде всего необходимо добавить в компоненте Notes метод, который будет заниматься полной переиндексацией новостей. Пусть этот метод будет находиться в отдельно модуле Utils.
// components/Notes/lib/Utils.php class Component_Notes_Utils implements Core_ModuleInterface { public static function reindex() { // Удалим из индекса все записи данного типа CMS::objects()->indexer->delete_documents('notes'); // Инициализируем счетчик записей $cnt = 0; // Добавим все новости в индекс foreach(CMS::orm()->notes->select() as $row) { $url = Component_Notes_Router::view_url($row); CMS::objects()->indexer->add_document('notes', $row->id, $row->title, $url, $row->content); $cnt++; } // Возвратим количество проиндексированных записей return $cnt; } }
Данный метод обязательно должен вернуть количество проиндексированных документов, т.к. поисковая система собирает эту информацию, обращаясь к данному методу в тех компонентах, где он определен.
Регистрация в системе
Теперь необходимо, чтобы поисковая система знала об этом методе и могла его вызвать. Для этого можно организовать вызов этого метода из другого класса, который загружен всегда. Например, Component_Notes:
//components/Notes.php class Component_Notes extends CMS_Component { ... static function reindex() { Core::load('Component.Notes.Utils'); return Component_Notes_Utils::reindex(); } }
И последнее: в методе initialize() модуля '''Component.Notes необходимо добавить директиву регистрации метода в поисковой системе.
//components/Notes.php class Component_Notes extends CMS_Component { public static function initialize($config = array()) { parent::initialize($config); CMS::add_command('indexer', 'reindex', array('Component_Notes','reindex')); } }
Переиндексация из командной строки
Полную переиндексацию сайта можно проводить из командной строки. Для этого в компоненте предусмотрен метод ftsearch_reindex, который запускается в командной строке.
php index.php ftsearch_reindex