Пошаговая инструкция настройки Search API для поиска с морфологией.
Кто пользуется встроенным в друпал модулем поиска и по каким то причинам не хочет использовать Search API, тому достаточно включить модуль Russian stemming и сделать переиндексацию индекса на странице admin/config/search/settings . После этого поиск с морфологией заработает без дополнительной настройки.
Настройка Search API
Отключаем модуль Search.
На странице admin/config/search/search_api добавляем новый сервер с классом Database service:
На странице admin/config/search/search_api переходим в настройки дефолтного индекса:
Изменяем сервер на созданный ранее и сохраняем изменения:
На странице admin/config/search/search_api включаем дефолтный индекс:
На странице admin/config/search/search_api переходим в настройки Workflow у дефолтного индекса:
В блоке Processors включаем Russian stemmer:
На этой же странице изменяем порядок процессоров так, чтобы Russian stemmer оказался последним и сохраняем изменения:
На странице admin/config/search/search_api переходим по ссылке Status дефолтного индекса:
Запускаем индексирование с помощью кнопки Index now:
После окончания индексирования проверяем таблицу search_api_db_default_node_index_body_value . В ней должны быть слова без окончаний:
Настройка Views
Включаем модуль Search views из состава Search API.
Создаём страницу представления по дефолтному индексу и с выводом Rendered entity:
Добавляем раскрытый фильтр Search: Fulltext search
В настройках фильтра выбираем оператор Contains any of these words, а в поле Searched fields все поля из индекса, по которым будет происходить поиск:
Подробнее про Search API:
Написанное актуально для Drupal 7 Похожие записи
Комментарии
для больше наглядности результата(пункт 5) я бы добавил в процессоры highlighting ,а в сам текст несколько словоформ
И база данных сразу не хило так разжиреет. в зависимости от количества уже имеющегося контента.
не больше чем от стандартного модуля Search
Раз уж речь зашла о Search API и Search Views, не могу не спросить, может сталкивались: как на странице результатов поиска выводить запрос (в заголовок, например)?
Пробовал играться с contextual filters — не работает.
xandeadx А Sphinx будет не лучше?
зависит от задачи
xandeadx задача организовать как можно более ролевыантный поиск
Вы написали: "Кто пользуется встроенным в друпал модулем поиска и по каким то причинам не хочет использовать Search API. "
А надо ли использовать модуль Search API если можно и со стандартным поиском искать с морфологией? Т.е. что дает использование Search API по сравнению со стандартным?
почитайте описание Search API
Читал про возможности Search API (но не пользовался), меня интересовало именно качество поиска с морфологией — есть ли разница.
разницы нет, принцип один
Подсветка только в поиске по слову работает 🙁
Тогда смысла вообще нет в сиём творении если по части слова подсветить нужно результат. Ну или руками или JS-ом.
Все поставил, все настроил, все круто работает, но после отключения search пропадает блок с формой поиска, который выводился на всех страницах сайта и после введения слов в который собственно на страницу поиска и попадали раньше.
Не соображу как вернуть поле формы поиска на все страницы сайта при использовании Search API?
вынесите раскрытый фильтр в блок
Спасибо за статью. Подскажите а как быть если я подключаю модуль search api autocomplete. У меня подтягиваются результаты — автокомплит работает. Проблема возникает если я фильтрую по терминам — дополнительно к поиску. Как сделать чтоб в автокомплит попадали только данные, ноды которых связаны с выбранным термином. То есть что то наподобии фасетного поиска.
Спасибо за статью, в который раз к ней возвращаюсь.
Но тут возникла маленькая проблема:
поиск тупо игнорирует цифру "0". Если вводить 100 — находит значения в которых есть 100, если 001 — ищет только 1.. Просто ввести 0 — все остается на месте. Через фильтр по заголовкам такой проблемы нет, если заголовки брать из индекса ноль не ищет. Грешу на токенайзер, может где пробельные символы что ввести? Подскажите пожалуйста, уже всю голову сломал.
Хотя если токенайзер отключить ничего не меняется..
Спасибо за статью! Сэкономил кучу времени 🙂
Александр, может быть дело в настройке минимальной длины поискового слова? На первом скриншоте последний select
Поддерживаю вопрос в комменте выше — Как сделать чтоб в автокомплит попадали только данные, ноды которых связаны с выбранным термином.
Похоже, что для D8 затык именно в RussianStemmer, т.к. Database search стал частью search_api. Я так понял, RussianStemmer – это переделанный porterstemmer под русский сноубол Портера.
Привет! Есть проблема с этим модулем. Интересно, что если в заголовках многих статей на сайте имеются словосочетания написанные через дефис (например "контрольно-измерительные"), и в форму поиска ввести такое сочетание, то поиск не дает результатов вообще. Даже если вводить это сочетание без дефиса, результатов нет. Но стоит в настройка установить галочку Search on parts of a word, то искомый запрос находится, однако поиск очень медленный. Кажется, что этот модуль по каким-то причинам причинам не воспринимает такие словосочетания и не индексирует их. Пожалуйста, ответьте, сталкивались ли Вы с такой проблемой? Или можете дать совет? Благодарю Вас!
смотрите что в индексе, и какая фраза уходит при поиске
/new-search?query=Контрольно-измерительные%20материалы — вот что уходит при поиске
контрольнизмерительн материал -Это в индексе
Ума не приложу, как разделить при индексировании "контрольнизмерительн".
смотрите что уходит в запросе к базе, а не в адресе
Странно, но даже по запросу "контрольнизмерительн материал" — результат нулевой.
Извините, как и где я могу это посмотреть?
спасибо. тему не закрываю
С помощью Devel?
Спасибо за статью.
А есть ли способ настроить поиск по части слова? Что-то я перерыл много материала по Search API c SOLR и без него, но так и не нашел решения ни в рунете ни за ним.
Например у меня пустой результат, если искать "welcom", а если дописать "welcome" — то сразу все хорошо. Как же быть? Спасибо.
К предыдущему комментарию забыл дописать, что интересует именно поиск по произвольной части слова. Не морфологический поиск (по однокоренным), который настраивается по словарям или с помощью Stemmer.
Предыдущий припер с welcome — именно об этом, и кроме того всякие аббревиатуры и сокращения тоже не подпадают под морфологию, а искать их приходится.
В настройках сервера есть опция "Search on parts of a word"
Гость, скорее всего нет..
Перепробовал разные варианты но поиск так и продолжает игнорировать 0 вначале строки, и по запросу 000 выдает пустое значение.
На форуме посоветовали смотреть search API -> API + hook’s, пока не разобрался.
Установил, настроил. Автору большое спасибо!
Собственно теперь вопрос по транслитерации. Если ввожу часть слова на английском, на пример, asp — это артикул товара, то получаю кучу страниц с русским вхождением в состав слова букв "асп" аспираторный, на пример. Если отключить транслитерацию поиск перестает работать. При чем вхождение именно asp в состав слова выдает на 10 месте. Наверное как-то нужно настраивать релевантность выдачи. Можно ли это как-то победить, или я в настройках накосячил.
Зачен интересно отключать module Search? У меня и так все отлично работает
Стандартный поиск достаточно уныл и плохо поддаётся изменению. Немного скрашивает ситуацию модуль Custom Search, но например изменить количество результатов на страницу не способен даже он.
Выход — оставить модулю Search функцию индексирования, а поиск по индексу и вывод результатов возложить на Views:
- Создаём представление по содержимому.
- Добавляем дисплей Page.
- Меняем путь страницы на search2 , чтобы не было конфликтов с модулем Search.
- Добавляем раскрытый фильтр по Search: Search Terms
- Удаляем сортировку по дате.
- Добавляем сортировку по Search: Score с типом Sort descending.
- По желанию — меняем стиль, добавляем/удаляем поля, добавляем новые фильтры, выносим форму с раскрытыми фильтрами в блок.
Написанное актуально для Views 3 Похожие записи
Комментарии
а если сюда еще прикрутить search_api, search_api_facets и search_api_sorts вобще красота получается.
Возможно не совсем в тему, но все же: подскажите пожалуйста, каким образом можно организовать форму поиска в виде блока, как, например на httр://auto.ria.ua/ (форма красненького цвета)?
воспользоваться раскрытыми фильтрами, вынести фильтры в блок
Ну в общем разобрался кроме одного: как задать интервал, например, цена от и до в фильтре. Может подскажете еще и куда здесь копать?
оператор Is between
Хм. Этот оператор вроде работает только если цену ручками вбивать в поле фильтра, а вот можно ли сделать для цены внесенной в БД в виде текстового поля аналогичный выпадающий список, как при выборе терминов таксономии в фильтре для views?
для текстовых полей нет
Например, задача, сделатьсайт объявлений по продаже автомобилей на Drupal 7. Организовываем поиск марок, моделей, региона и т.п. + кнопочка "Применить"(Поиск) с помощью фильтров Views в виде блока на главной.
Это несколько неудобно, нам требуется отобразить много информации кроме результатов поиска машин, например еще свежие новости, краткий каталог сервисов и т.п. .
Поэтому пытаемся создать для этой же Views страницу, куда бы перекидывало с такого блока при выборе определенных фильтров и клика по кнопочке "Применить фильтр", причем сам данный блок поиска машин на главной странице выводился бы только с одними фильтрами и без результатов, а страница, сделанная с помощью views, все параметры фильтров брала бы из URL, переданных от фильтра с главной страницы, но не имела видимых фильтров.
Пытаясь решить данную задачу зашел в тупик, ибо:
1) форма поиска в виде блока (фильтры Views) на главной странице отображается только если используется AJAX, причем результаты фильтрации отлично выводятся тут же на главную, а как заставить показываться только саму форму с фильтрами без результатов в виде полей, причем при клике по кнопочке применить шла переадресация на страницу с результатами поиска(страница Views того же представления) так и не понял;
2) страница (не блок!), где должны отображаться результаты нашего поиска без видимых фильтров, действительно показывает все нужные поля без фильтров, вот только нивкакую не хочет из URL (GET-запрос) брать параметры для фильтрации, и тупо отображает все результаты.
Подскажите, кто-нибудь, что я делаю не так?
вынесите раскрытые фильтры в блок
выведите блок в регион
profit
Т.е. оставить в блоке одни фильтры без полей для результатов, так?
А как тогда настроить фильтры для страницы, чтобы она принимала значения фильтров из блока упомянутого выше блока и обрабатывала результаты согласно значениям в фильтрах?
ничего настраивать не нужно, результаты будут выведены на отдельной странице
Да что-то не выходит.
Вот настройки блока, а вот настройки страницы.
Пытаюсь убрать поля в блоке- вьюха говорит ошибка, блок не может быть без полей, ну и, соответственно, т.е. одни фильтры оставить не получается.
Уже мозги закипать начали, а просвета нет.
А если AJAX отменить то вообще ничего блок не показывает, ни формы с фильтрами, ни результатов. А с включенным AJAX форма показывается вместе с результатами.
дисплей должен быть один — страница
А для блока другую вьюху создавать, так получается?
нет. в настройках вынесите фильтры в блок
Ага! щас попробуем!
Огромное спасибо, таки получилось то, что хотелось благодаря вашей помощи!
Кста, насчет раскрытых фильтров в блоке созданном views. Если использовать Глобальный: Dependent filter, и выводить раскрытую форму в блоке, то фильтр работает нормально, а если усложнить задачу и в этой вьюхе добавить еще страничку клонированием предыдущей, только изменить 1 скрытый фильтр и адрес страницы, и вывести обе раскрытых формы в блоке на главной странице (получим поиск аналогичных параметров по 2 скрытым категориям), то в верхней форме в блоке Глобальный: Dependent filter работает правильно, а для второй формы в блоке на той же странице Глобальный: Dependent filter работает уже неправильно, т.к. не открывает скрытые с помощью него раскрытые фильтры.
Причем при смене последовательности отображения этих 2 блоков с раскрытыми фильтрами ошибка с Глобальный: Dependent filter повторяется, и нормально работает тот блок, который окажется выше в структуре регионов.
Как бы заставить этот Глобальный: Dependent filter работать корректно с 2 аналогичными формами на одной странице, есть соображения?
столкнулся с той же проблемой..
уже третьи сутки долбусь — никак не выходит создать блок, который бы не выводил результаты поискового запроса в своем теле.
можно поподробней о том, как в настройках вынести фильтры в блок.
Advanced — Exposed form — Exposed form in block — Yes
Как в воду глядел — вся загвоздка в нюансе. Но не думал — ни гадал, что в таком элементарном! Спасибо!
Здравствуйте, подскажите а как можно сделать чтобы этот поиск искал по буквам и частям слова?
добавьте раскрытый фильтр
А где он находится, а то я не вижу? Спосибо
Здравствуйте!
Ничего не понимаю, сделал всё так как вы написали, захожу на страницу /search2/ а там у меня пусто — только один заголовок, а формы поиска никакой нет, что делать то??
значит не всё сделали
Великолепно!! Спасибо, ещё раз всё сначало сделал повнимательней и заработало.
Подскажите пожалуйста — есть ли модуль для друпала смысл которого:
пользователь заполняем поля в своей анкете — и отображается % заполнение анкеты.
Извините, если не в том месте пишу.
Здравствуйте xandeadx, хотел заменить стандартный поиск на views по вашей статье, но не радуют результаты поиска. К примеру слово "ручка" находит а вот "ручку" уже нет.
Использую раскрытый фильтр "Search: Search Terms"
Для этого, как вариант — добавить несколько раскрытых фильтров, но строка поиска должна быть одна, что посоветуете для таких случаев??
гуглите по фразе "поиск с морфологией"
Ищет только по заголовку материалов?
Блин, полдня убил на эту тему. Для тех, кто не может понять почему артикул товаров ubercart не индексируется модулем поиска drupal (ну и для гугла): search module индексирует всё, что будет выводиться в node.tpl.php (но перед отправкой в node.tpl.php). Так что надо в отображение полей товара в настройках уберкарта добавить артикул, чтобы он попал в индекс, ну а скрыть его, если он не нужен, можно с помощью CSS или в шаблоне node.tpl.php
Добрый день, столкнулся с той же проблемой, что и evgeniy — на странице отсутствует форма поиска, только мне метод "сделать заного и повлнимаьтельнее" не помог.
Можете что-нибудь подсказать?
Search API мощный инструмент для организации поиска на сайте, и уметь осуществлять поиск программно — очень полезный опыт. Задачи, решаемые программным поиском, могут быть разные, но потребность так или иначе со временем может появиться.
Програмный поиск с использованием Search API состоит из нескольких самостоятельных частей самого модуля: поисковый индекс, режим парсинга и менеджера запросов. А также вытекающий из этого результат поиска.
Поисковый индекс (Search API Index) — это сущность-конфигурация, которая хранит информацию о поисковых индексах. Это то, что вы настраиваете в админке Search API. Нужные нам методы:
- load() : Загружает сущность индекса по его машинному имени. Так Search API будет знать куда осуществлять поиск.
- query() : Создает и возвращает инстанс SearchApiQuery для выполнения в данный индекс.
Режим парсинга (Parse Mode) — это плагины, которые отвечаю за то, как текст переданный для поиска будет обрабатываться. Для поиска создается инстанц плагина, того типа парсинга, который будет использоваться при поиске и передается в поисковый запрос. В нем всего один полезный для нас метод:
- setConjunction() : Данный метод может принимать ‘AND’ и ‘OR’ . По умолчанию, если не устаноивить, он будет использовать ‘AND’ . Этот параметр определяет то, как полученные ключи для поиска, при помощи выбранного вами плагина Parse Mode, будут обрабатываться. При ‘AND’ — все ключи должны присутствовать в материале который ищем, ‘OR’ — любой из ключей, один или более. Не все плагины режимов парсинга поддерживают смену данного значения. У некоторых он может быть прописан жестко прямо в плагине.
По умолчанию в ядре имеются следующие Parse Mode плагины:
- phrase : Поиск по определенной строке. Разбивает строку на массив ключей и принудительно используется setConjunction() = ‘AND’ . Это значит, что будет искать те материалы, где все слова из поисковой строки присутствуют.
- direct : Аналогично phrase , только совершенно не обрабатывает строку, из-за чего могут быть проблемы с синтаксисом при запросе. На стандартном Database Server он ничем не будет отличаться от phrase , он также имеет условие ‘AND’ для ключей. Но вот, допустим, если подключить Solr или что-то ещё серьезное, то данный способ будет учитывать синтаксис поискового движка и его особенности и не будет очищать запрос от них.
- terms : Разбивает строку на ключи и ищет их вхождение. Здесь уже работает setConjunction() и вы сами определяете как поиск будет производить поиск по ключам.
Если вы вдруг захотите узнать все доступные плагины для парсинга на проекте, выполните данный код:
Поисковый запрос (Search API Query) — объект для построения запроса к поисковому индексу. Вот этот объект нам уже намного интереснее, так как он в итоге делает всю основную работу, и методов, полезных нам, тут будет больше всего (они не все, а лишь самые полезные).
- setParseMode() : Устанавливает режим парсинга для данного запроса. В него нужно передать инстанс нужного плагина Parse Mode.
- keys() : Указывается строка для поиска, она и будет использована для парсинга при помощи указанного плагина Parse Mode. Вы также можете не указывать Parse Mode и передать в данный метод массив с нужными для вас ключами и способм поиска по ним. Массив должен содержать #conjunction элемент со значением. Пример: [‘lorem’, ‘ipsum’, ‘#conjunction’ => ‘AND’] . Таким образом, можно сделать указание Parse Mode необязательным или игнорировать его. Можно также передать NULL , в таком случае будут выбраны вообще данные из поискового индекса.
- setFulltextFields() : Позволяет указать массив из имен полей (поискового индекса) типа fulltext по которым будет происходить поиск. Этот метод позволяет задать ограничение на данные поля, если метод вызвать пустым, или не вызвать вообще, то в таком случае поиск будет производиться по всем fulltext полям из индекса.
- range() : Позволяет огарничить результаты как и обычный запрос. Передается смещение и лимит результатов относительно смещения.
- addTag() : Позволяет задать тег запросу. Это полезно чтобы другие модули могли вмешиваться в альтер запроса и точно определять что это он. Для этого есть hook_search_api_query_TAG_alter() . Можно задавать несколько тегов, для этого данный метод нужно вызывать несколько раз.
- setProcessingLevel() : Позволяет задать уровень обработки запроса. Может иметь следующие значения:
- QueryInterface::PROCESSING_NONE — никакие обработчики настроенные у поискового индекса не будут вызваны.
- QueryInterface::PROCESSING_BASIC — будут вызваны только базовые процессинги, например фасеты, проверка правописания.
- QueryInterface::PROCESSING_FULL (по умолчанию) — будут вызваны все обработчики установленные и настроенные для индекса.
Если вы знакомы с PDO запросов от Drupal, вам многие вещу уже должны быть знакомы. Есть свои особвенности типа спец. полей, но в целом, всё аналогично.
Набор результатов (Result Set) — объект содержащий результаты выполнения запроса (поиска). Нам интересны лишь два метода:
- getResultItems() : Возвращает массив результатов состоящий из Drupalsearch_apiItemItem объектов.
- getResultCount() : Возвращает кол-во результатов по вашему запросу итого. Например, если указали range(0,5) , вы получите 5 результатов Item , но по факту там может быть 100 материалов, этот метод вернет это кол-во.
Элемент результат поиска (Item) — объект, содержащий информацию о конкретном результате поиска. Полезные методы:
- getOriginalObject() : При вызове вернет объект DrupalCoreEntityPluginDataTypeEntityAdapter где есть вся необходимая информация из сущности, и сама сущность ->getValue() . Если все нужные вам поля для формирования результата поиска имеются в виде полей индекса, обращайтесь к ним напрямую.
- getField() : Возвращает инстанс Drupalsearch_apiItemField поля. Для того чтобы получить итоговое значение нужно вызывать дальше: $result_item->getField(‘title’)->getValues() .
- getFields() : Аналогично методу выше, только возвращает все доступные поля.
- getScore() : Возвращает какой результат был присвоен данному результату.
- checkAccess() : Передав в него объект пользователя, проверяет, имеет ли пользователь доступ к данному результату поиска.
- getExtraData() : Позволяет получить доступ к дополнительным данным результата. Они могут добавляться различными процессорами. Чтобы узнать что там есть, проще всего вызывать getAllExtraData() и посмотреть. Например, если у вас включена подсветка найденного вхождения, то оно будет доступно по ключу highlighted_fields .
Это самые ходовые методы по каждому из разделу, остальные уже можно поглубже откапать в конкретных объектах.
Время посмотреть на примеры. Далее по коду подразумевается что модуль имеет название dummy.
У меня нет особо конкретных примеров и долго было бы под каждый подбирать индексы и данные, поэтому примеры в данном материале будут почти все "голые", я думаю не составит труда понять как их использовать под свои нужды, так как код можно вызывать откуда угодно.
Пример №1 — Минимальный набор для поиска
Для того чтобы просто вызывать поиск в индексе, достаточно выполнить следующий код.