Живой поиск на Drupal

Аватар пользователя gun_dose
13

Здарова, щеглы! Сегодня я вам расскажу, как сделать живой поиск на друпал. Для этого нам понадобятся:

 Search API
 Search API Database Search
 Search API pages
 Search API live results
Скачиваем и включаем все эти модули вручную или по-нормальному через
drush en search_api search_api_db search_api_page search_api_live_results -y
Затем идём в "Конфигурация - Поиск и метаданные - Search API - Добавить сервер" и заполняем там поля, как показано на картинке ниже. Поле "минимальная длина слова" определяет, после ввода скольких символов будут появляться результаты. Один символ - это насилие над базой данных, а вот 3-5 - в самый раз. Галочка "Искать по частичным совпадениям" означает, что поиск будет вестись по фрагментам слов. Если её не выставить, то результаты будут находиться только по целым словам, что не всегда удобно.
db_server
Теперь, когда у нас есть сервер, можно создать поисковый индекс. Идём аналогично - "Конфигурация - Поиск и метаданные - Search API - Добавить индекс" и заполняем там поля следующим образом: имя - любое вменяемое имя, машинное имя, согласно правилам для машинных имён drupal, "Тип элемента" - тип сущности (материал(нода), термин таксономии и т.д. Тут как правило, имеет смысл выбирать именно материал, если у вас есть например связанные продукты commerce - их поля потом можно будет также добавить. "Наборы" - выбираем те типы материалов, которые собираемся индексировать. Тут важно не забыть никакой тип, но и не ставить галочки туда, куда не надо, чтобы не захламлять базу данных. В поле "Сервер" выбираем наш только что созданный сервер. "Только чтение" - не трогаем, оставляем невыбранным. "Проиндексировать элементы сразу" - выставляем обязательно. Если не выставить, то новые материалы в индексе будут появляться только по крону, если же выставить, то любые изменения будут индексироваться сразу. "Cron batch size" - оставляем, как есть - 50. Это означает, что если есть что-то неиндексированное, то по крону будет индексироваться по 50 элементов. Сорри, что не сделал скрин - он был бы слишком длинный и не очень информативный :)

После нажатия кнопки сохранить нас перебросит на форму добавления полей в индекс. Я обычно выбираю в добавок ко всему остальному тип материала и ID. Для живого поиска выбираем заголовок и Body. Если у вас есть ещё какие-то важные текстовые поля, выберите и их. Важно: выбирайте для текстовых полей тип Fulltext, т.к. в Fulltext можно производить поиск по фрагментам текста. Однако, Fulltext не позволяет делать сортировку, для этого нужен тип "Строка". Если же вы хотите искать и сортировать по одному и тому же полю, то это можно настроить на вкладке "Фильтры" в настройках поискового индекса, но об этом я расскажу как-нибудь в следующий раз :)

Если вы ищете в полях Body, не отчаивайтесь. Текст с форматом ввода - это сложносоставное поле, поэтому его нужно добавлять как связанное поле. Да-да, вот там внизу кнопка "Добавить связанные поля". Но прежде чем жать эту кнопку, сохраните форму, иначе внесённые изменения потеряются! Такая вот засада. На этом с поисковым индексом пока всё.

Теперь нам нужна форма поиска для нашего поискового индекса. Стандартная форма нам не подходит, т.к. это вообще другой поиск. К слову, при использовании Search API стандартный модуль поиска Search лучше отключить и анинсталлить. А для формы поиска нам нужен модуль Search API Pages. Идём в "Конфигурация - Поиск и метаданные - Search API - Страницы поиска - Добавить страницу поиска". Там всё просто - вводим заголовок поисковой страницы и её путь, выбираем наш поисковый индекс, остальное по вкусу и согласно здравому смыслу.

И последний шаг - включить живой поиск. Для этого идём на страницу редактирования поискового индекса, заходим на вкладку Live Results и ставим галочку напротив недавно созданной страницы поиска. Сохраняемся. Если нажать "Изменить", то можно задать количество выпадающих результатов и тип отображения - просто кликабельное название либо стиль отображения live results search. К слову, этот стиль отображения полностью настраивается в настройках отображения материала, а также есть шаблон для него, который можно найти в папке модуля. Естественно, для переопределения шаблона надо скопировать его в свою тему.

Форма поиска доступна как блок на странице управления блоками. Также её можно вызвать программно:

<?php
$search_page 
entity_load_single('search_api_page'1);
$search_form drupal_get_form('search_api_page_search_form_search'$search_page);
?>

Поздравляю! Теперь ваш сайт стал чуточку менее колхозным, ведь около 100% разработчиков практически не волнуются о том, как работает окошко поиска на сайте, в результате чего оно не всегда работает в принципе. А если вы сделали всё по инструкции, то у вас должна получиться красота такая же, как на картинке в начале статьи. Ну само собой, что надо ещё немного поверстать, чтобы оно смотрелось как на этой картинке:
Живой поиск

PS: на всякий случай, не надо путать live results и автокомплит, т.к. у них в корне разное поведение. Если по клику на живой результат вы переходите на его страницу, то по клику на вариант из автокомплита этот вариант просто вставляется в окно ввода текста и это логично, ведь автодополнение должно просто помогать вводить данные и ничего более.

И в качестве спама, ссылка эту статью в моём говноблоге, в который впрочем, кроме этой статьи, я за два года ничего толкового не написал.

Модули и темы:
Ключевые слова:
Тип материала:
Версия Drupal:

Комментарии

Аватар пользователя xSPiRiTx
xSPiRiTx 1 год назад
1

ОТЛИЧНО!
СПАСИБО!
попробую на восьмерке воспроизвести.

Аватар пользователя dgastudio
dgastudio 1 год назад

gun_dose, вопрос: а почему search_api_pages вместо views?

Аватар пользователя gun_dose
gun_dose 1 год назад
1

Только потому что он даёт форму поиска. И live results заточен под неё. А сама страница поиска легко темизируется - можно настроить, какой режим отображения выводить и есть шаблон страницы, можно, например, повыпиливать вывод некоторых элементов, таких как время выполнения запроса.
Естественно, что под поисковые фильтры нужен вьюс. Тут речь только о текстовом поиске. И выводить те же фасеты на странице текстового поиска смысла нет, т.к. выборка может быть слишком разношёрстная.

Аватар пользователя bumble
bumble 1 год назад
1

А вот от меня - отдельное спасибо за search_api_pages!
Как-раз искал варианты работы с Search API без Views.

Аватар пользователя bumble
bumble 1 год назад
2

На главной.

Аватар пользователя VasyOK
VasyOK 1 год назад
1

На последнем "прожекте" чуть по другому делал. Без Search api (решили не использовать). search_autocomplete + открытые фильтры во вьюхе http://www.ukrigrushka.com.ua/

Аватар пользователя gun_dose
gun_dose 1 год назад

Я в таком варианте не понял, как сделать переход по ссылке при клике на вариант - он тупо вставлялся в текстовое окно.

Аватар пользователя VasyOK
VasyOK 1 год назад
1

Не помню, чтобы было проблемой. Делаю так уже не первый раз. Ок, я свой вариант в другом посте распишу.
Написал тут: http://drupal.ru/node/130923

Аватар пользователя gun_dose
gun_dose 1 год назад

Да, точно, это на Search API Autocomplete была проблема. Что-то твой сайт подозрительно быстро работает))

Аватар пользователя VasyOK
VasyOK 1 год назад

Я ж говорю: там нет Search API. Быстро? Ниче вообще не делал для этого. ДАже не включит то, что должно быть включено в производительности.

Аватар пользователя Studio VIZA
Studio VIZA 1 год назад

Огромное спасибо за статью, обычно в этом месте :

gun_dose написал:
Добавить сервер" и заполняем там поля

я понимал что добавить сервер мне ну никак ))
С живым, конечно сайт няшка.

Аватар пользователя tooez
tooez 1 год назад
VasyOK написал:
На последнем "прожекте" чуть по другому делал. Без Search api (решили не использовать). search_autocomplete + открытые фильтры во вьюхе http://www.ukrigrushka.com.ua/

А можно чуть подробнее? Сайт у вас действительно быстро работает!

Аватар пользователя VasyOK
VasyOK 1 год назад

Нет у меня секретов. 1-й самый дешевый аккаунт Патруля. Там и 1000 товаров нет.

Аватар пользователя tooez
tooez 1 год назад

У меня после попытки поиска выбивает ошибку:
PDOException: в функции locale() (строка 749 в файле E:\WebSites\site\modules\locale\locale.module).
На сайте произошла непредвиденная ошибка. Пожалуйста, повторите попытку позже.

Поиск работает (вылезают материалы по словам), но если просто ввести слово и нажать "поиск", то выдает страницу с ошибкой выше.

Аватар пользователя gun_dose
gun_dose 1 год назад

Проверьте в поисковом индексе, выбрано ли поле язык и в конфигурации страницы поиска, что стоит там в настройках языка. Хотя я никогда не трогал эти настройки и всё работает

Аватар пользователя tooez
tooez 1 год назад
1
gun_dose написал:
поле язык и в конфигурации страницы поиска

Я тоже это не выбирал - делал, Как у вас написано! Вечером попробую.
Спасибо за статью! И блог у вас здоровский )

Аватар пользователя tooez
tooez 1 год назад
gun_dose написал:
в моём говноблоге

а как вы такой вид страницы в блоге сделали?

Аватар пользователя gun_dose
gun_dose 1 год назад

Ловкость CSS и никакого мошенничества))

Аватар пользователя gun_dose
gun_dose 1 год назад

Я даже могу сказать, сколько я на этом заработал: 10,49$ с августа 2014. Сумасшедшие деньжищи!))

Аватар пользователя sergeybelya
sergeybelya 1 год назад

Да дело не в деньгах, а в несоответствии слогану сайта) Посетитель же не знает, сколько вы заработали. И внизу по сути идет реклама, какой вы крутой разработчик и беретесь за проект любой сложности) В этом ничего плохого нет, но это все же реклама.

Аватар пользователя gun_dose
gun_dose 1 год назад
1

Осмелюсь возразить, но это не реклама:
не реклама!!!

Мне действительно плевать на заказы, я завязал с фрилансом и не собираюсь никому делать за 5 долларов обтекание картинок текстом.

Аватар пользователя gun_dose
gun_dose 1 год назад

Ну да, есть такое. Надо этот сайт вообще тотально отрефакторить. И перевести на 8-ку, но я не умею пока)) Да и вообще в лом)) Но спасибо за замечания, я только сейчас понял, что серьёзно рискую нарваться на шквал писем о заказах.

Аватар пользователя sergeybelya
sergeybelya 1 год назад

Ну не знаю насчет шквала, но у меня бывало по несколько в месяц, приходилось отписываться. Восьмерку поковыряйте, думаю, не пожалеете, она те такая уже и плохая, у нее кстати есть миграция контента в коробке с предыдущих версий, но у вас тема довольно кастомная, придется повозиться. Хотя лучше на коммерческом проекте конечно.

Аватар пользователя tooez
tooez 1 год назад
gun_dose написал:
Ловкость CSS и никакого мошенничества))

Исключительно ксс? Думал, модули какие то ) Тогда, сам смогу сделать ))
И не стыдно вам людей обманывать? Миллионы на рекламе делаете, а прикидываетесь бедняком..

Аватар пользователя tooez
tooez 1 год назад
sergeybelya написал:
Восьмерку поковыряйте

есть резон на восьмерку садиться?

Аватар пользователя sergeybelya
sergeybelya 1 год назад

Естественно, она уже год как вышла.

Аватар пользователя tooez
tooez 1 год назад
sergeybelya написал:
Естественно, она уже год как вышла.

Много модулей адаптировано? Я недавно сайт начал делать на семерке. Побоялся восьмую ставить.

Аватар пользователя sergeybelya
sergeybelya 1 год назад

Там многое есть в коробке, по специфичным модулям нужно смотреть.

Аватар пользователя tooez
tooez 1 год назад

Прямо сейчас поставлю и буду шариться ) Спасибо!

Аватар пользователя HardHardy
HardHardy 11 месяцев назад

Спасибо за статью!
А не подскажете решение
Пытаюсь вывести программно

<?php
$search_page 
entity_load_single('search_api_page'1);
$search_form drupal_get_form('search_api_page_search_form_search'$search_page);
?>

выдает ошибку

  • Notice: Undefined index: search_api_page_search_form_search в функции drupal_retrieve_form() (строка 807 в файле /var/www/p155471/data/www/site.ru/includes/form.inc).
  • Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'search_api_page_search_form_search' not found or invalid function name в функции drupal_retrieve_form() (строка 842 в файле /var/www/p155471/data/www/site.ru/includes/form.inc).

Что не так?

Аватар пользователя gun_dose
gun_dose 11 месяцев назад

search_api_pages точно включен? Страница поиска создана?

Аватар пользователя HardHardy
HardHardy 11 месяцев назад

Да, все включено, настроено и работает. Кроме программного вывода

Еще при использовании поиска летят ошибки

Strict warning: Only variables should be passed by reference в функции search_api_live_results_json() (строка 23 в файле /var/www/p155471/data/www/site.ru/sites/all/modules/search_api_live_results/includes/search_api_live_results.pages.inc).

Аватар пользователя gun_dose
gun_dose 11 месяцев назад

Проверьте тогда машинное имя своей страницы поиска. Там в самом модуле форма вызывается так:

<?php
$block
['content'] = drupal_get_form('search_api_page_search_form_' $page->machine_name$pageNULLTRUE);
?>

А ошибки эти - косяк модуля. Там в render() засунуты функции, а не переменные, если сначала выполнить то, что внутри рендера и передать в него переменную, то будет норм. Не стал искать патчей на такую мелочь и пофиксил сам, хоть это и не комильфо))

Аватар пользователя HardHardy
HardHardy 11 месяцев назад

не могу понять
какое машинное имя?
Путь страницы поиска указал - /search_page
В live-results когда изменить тыкаю в адресной строке строке - /search_api_page_1/edit

пробовал в строчку $search_page = entity_load_single('search_api_page', 1); вместо 'search_api_page' подставить search_page или search_api_page_1
у меня сразу фатал еррор
Fatal error: Class name must be a valid object or a string in /var/www/p155471/data/www/site.ru/includes/common.inc on line 8041

Метод тыка на этом у меня исчерпан :) :'(

Аватар пользователя gun_dose
gun_dose 11 месяцев назад
1

Значит, попробуйте так

<?php
$search_page 
entity_load_single('search_api_page'1);
$search_form drupal_get_form('search_api_page_search_form_search_page'$search_page);
?>

Всё просто - у меня путь поисковой страницы search а у вас search_page.

Аватар пользователя HardHardy
HardHardy 11 месяцев назад

Да, теперь ошибок нет. Но и формы поиска не наблюдается... При просмотре кода страницы вообще ничего не выводится.
Переделал как у вас. Результат тот же форма поиска не выводится. Сама страница работает

В общем вывел блок таким образом

<?php
$block 
block_load("search_api_page""search");
$render_array _block_get_renderable_array(_block_render_blocks(array($block)));
echo 
render($render_array);
?>

Спасибо большое за помощь!!!

Аватар пользователя gun_dose
gun_dose 11 месяцев назад
1

Можно и так, просто я решил взять саму форму без обёрток. На трёх сайтах сработало. Тут ещё такой момент, что после экспериментов может оказаться, что айдишник сущности у страницы поиска не 1, а 2 или 3. Я, чтобы написать те две строки кода, изрядно порылся в базе и в коде модуля.

Аватар пользователя tooez
tooez 8 месяцев назад

Живой поиск работает, спасибо.
Одно понять не могу - если я пишу в поиск запрос, то вылезают нужные страницы, но если я нажимаю "найти", то страница поиска пустая.
Как это пофиксить?

Аватар пользователя gundertajlo1995@mail.ru
gundertajlo1995... 7 месяцев назад

будет сборка данных модулей с boost коректно работать?

Аватар пользователя Boozenok
Boozenok 7 месяцев назад

Подскажите, а если у меня есть товары с вариацией и у каждого товара есть свой артикул. Я хочу сделать поиск по названию и по артикулу. Если использовать для поиска ноды (одна нода-один товары), то тут все просто. А вот как лучше быть с вариациями товара? К примеру по названию еще можно, но как лучше организовать по артикулу, что бы срабатывал поиск как автокомплит, отсеивая неподходящие варианты.

Спасибо

Аватар пользователя gun_dose
gun_dose 7 месяцев назад

Надо добавить в поисковый индекс артикул товара, как поле fulltext. И вроде бы поставить галочку в настройках поисковой страницы.

Аватар пользователя Boozenok
Boozenok 7 месяцев назад

нет, так не помогает. оно ищет артикул, например, 13-1-0001 по всем товарам, но не отсеивается ненужные товары. Также если делать поиск по товару - не подтягивается view mode (((

Есть еще идеи?

Аватар пользователя gun_dose
gun_dose 7 месяцев назад

Вам, видимо, нужен индекс не по дисплеям, а по продуктам. А нужные поля дисплея, если не добавляются как связанные, то добавить через hook_entity_info_alter. С другой стороны, не совсем понятно, куда будет вести ссылка с результата, ведь у продуктов нет своих страниц.

Аватар пользователя igor2999
igor2999 4 месяца назад

Спасибо, все понятно.

Аватар пользователя void
void 3 месяца назад

gun_dose, не подскажите как заменить заголовок страницы поиска, созданной с помощью Search API pages с дефолтного, который прописывается в настройке созданной страницы на заголовок типа "Результат поиска по запросу <[ЗАПРОС]>"?

Аватар пользователя gun_dose
gun_dose 3 месяца назад

Не задавался такой целью. Надо поискать в модуле хуки препроцесса.

Аватар пользователя void
void 3 месяца назад

Вроде то, что надо. Вроде смотрел шаблоны, но проглядел. drupal_set_title меняет (из шаблона) метатег title, а вот сам заголовок h1 почему-то не меняет.

Аватар пользователя gun_dose
gun_dose 3 месяца назад
1

Да, обычно заголовок страниц задаётся другими способами, причём везде по-разному. Сказать по правде, нет времени вникать, что там и как устроено, но в качестве временного решения можно поставить в page.tpl.php условие, чтобы не выводить заголовок на странице поиска, а в шаблоне результатов поиска h2 заменить на h1.

Аватар пользователя void
void 3 месяца назад

Отличная идея! Спасибо!