UX/UI-рекомендации: разрабатываем идеальный внутренний поиск для E-commerce
Главная задача поисковой строки — быстро привести клиентов к тому, что они ищут. Поэтому важно, чтобы пользоваться ею было просто и удобно. Именно UX/UI Design решает такие вопросы. Сегодня рассмотрим, что же такое UX и UI: в чем разница и что их объединяет. Расскажем, как улучшить пользовательский опыт и пользовательский интерфейс страницы поисковой выдачи.
Дизайн имеет значение
Дизайн — это не то, как предмет выглядит, а то, как он работает.
Стив Джобс
Если дизайн удобен пользователям — совершить целевое действие будет легче. Так, в 1954 году Пол Моррис Фиттс открыл закон, который позволяет определять оптимальные размеры, зоны нажатия и расположение элементов интерфейса в соответствии с простотой их использования. Из главных тезисов исследований Фиттса можно выделить, что:
- чем больше цель (кликабельный элемент интерфейса) — тем проще и быстрее можно ее достигнуть;
- после определенного этапа увеличения цели — время ее достижения практически не сокращается. Проще говоря — не стоит делать объекты на сайте огромными, так как это не принесет значительного улучшения. Поскольку закон Фиттса — это двоичный логарифм, который является строго возрастающим или строго убывающим.
С момента открытия закона прошло уже более 60 лет, но он все еще активно применяется в проектировании и дизайне интерфейсов. Крупнейшие компании применяют эти закономерности, например, Amazon увеличил ширину окна поиска и поместил его ближе к адресной строке. В результате после ввода адреса веб-сайта и перехода на Amazon.com люди могут мгновенно попасть и в окно его поиска.
Поиск на Amazon
Ecommerce гигант подошел ответственно к разработке функционала строки, создал не просто отдел, а учредил свою компанию A9, нацеленную на производство технологий для поиска. A9 создали в 2003 году как независимую компанию со штаб-квартирой в Пало-Альто, Калифорния. Компания на протяжении 16 лет занималась развитием поиска на сайтах Amazon. Свое сотрудничество они прекратили после скандала в 2019 году из-за изменений в алгоритме строки в пользу более прибыльных для площадки продуктов.
Создаем идеальную строку поиска
В процессе проектирования поиска рекомендуем учитывать внешний вид, расположение и функциональность. Все эти аспекты работают вместе, чтобы сформировать более понятный и эффективный пользовательский опыт. В частности UX и UI окна поиска помогают сэкономить время посетителя и помогают ему попасть туда, куда нужно, с наименьшими затратами времени.
UX и UI — понятия разные, но раздельное их существование представить сложно. Отличный продукт всегда начинается с пользовательского опыта, за которым неотрывно следуют и его визуальные характеристики.
User Experience или UX (пользовательский опыт) — это ощущения пользователя, возникающие при взаимодействии с продуктом, сервисом или услугой. UX отвечает не только за красоту, функциональность и удобство, но и за эмоции пользователя. Цель UX — добиться, чтобы ваш продукт соответствовал коммерческим целям и задачам, доставлял клиентам положительные эмоции при каждом взаимодействии. Тем самым увеличил их лояльность к бренду.
User Interface или UI (пользовательский интерфейс) — это способ взаимодействия пользователя с продуктом, сервисом или услугой. UI фокусируется на том, как выглядит интерфейс: меню, поиск, фильтрация на сайте и другие элементы.
1.1. Внешний вид поисковой строки
Окно поиска нуждается в оформлении. Ведь есть ряд вещей, которые могут пойти не так. Например, текст, отображаемый в поле ввода, может быть трудночитаемым, или поле ввода может быть слишком коротким и пользователь не увидит весь текст своего запроса.
Внешний вид поисковой строки — обширное понятие, которое включает в себя большое количество параметров: цвет, размер, кнопка действия, иконка, текстовые подсказки и оформление результатов выдачи.
Рекомендуется включить пример поискового запроса в поле ввода. Он не только подсказывает пользователям, что они могут искать на вашем сайте, но и привлекает их внимание к строке. Но убедитесь, что текст подсказки исчезает, когда строка поиска становится активной.
Подсказка в строке поиска
Призыв к действию
Избегайте создания окна поиска без кнопки действия (CTA). Особенно в том случае, когда результаты выдачи не подтягиваются в real-time или после нажатия клавиши Enter. Поместите четкую кнопку призыва к действию непосредственно справа от строки поиска.
Пример правильного и неправильного оформления кнопки
Линза привычно распознается как символ поиска. Пользователи подсознательно ищут её, когда намереваются ввести свой запрос. Этот значок должен быть простым, с небольшим количеством деталей и контрастной интерактивной областью как изображено на примере ниже.
Иконка поиска
Поисковая строка на сайте должна быть заметна с первого взгляда — это делает ее более эффективной. Поможет в этом цвет — его можно распознать в первую очередь. Но необходимо учитывать цвет и визуальный контраст строчки по сравнению с остальной частью сайта.
Поле ввода лучше оставить белым, ведь не секрет, что текст лучше читается именно на этом фоне. А вот границы строки принято выделять ярким цветом, чтобы во время каждого сеанса покупатель легко улавливал ее визуально. Например, AliExpress для быстрого распознавания и взаимодействия выделил панель поиска ярким красным цветом.
Цвет поисковой строки
Увеличьте размер поля поиска, чтобы текст был полностью виден. Слишком короткая строка не мешает пользователям вводить длинные запросы, но все же плохо влияет на UX. Дело в том, что она препятствует процессу проверки и редактированию текста, поскольку видна лишь его часть.
Оптимальный размер поисковой строки должен вмещать 27-30 символов.
На примере видим, в какой строке места явно недостаточно, чтобы вместить длинный запрос.
Оптимальный размер 27-30 символов
1.2. Внешний вид страницы выдачи
Перейдем к визуализации результатов поиска:
Фото и цены в результатах выдачи
Очень важно, чтобы в результатах выдачи пользователи сразу видели изображение и цену продукции. Поскольку именно эти два элемента помогают клиентам быстрее сориентироваться и перейти на те товары, которые им действительно интересны.
Фото и цены
Количество результатов поиска
Когда клиенты видят количество товаров в выдаче, это помогает им понять, сколько же времени понадобится на их просмотр. На примере ниже видно, что на просмотр 698 записей уйдет немало времени. Это подтолкнет клиента использовать фильтры или уточнить запрос.
Количество товаров в выдаче
Поисковая выдача над разворотом
Термин «разворот» позаимствован веб-дизайнерами у полиграфистов. Это линия, по которой складывается газета. Концепция “видимой области” применима и в цифровых продуктах. Десктопные и мобильные версии ресурсов тоже имеют зону, видимую сразу после загрузки, и скрытый контент, ознакомление с которым требует дополнительных действий — скроллинга.
Пользователи прокручивают страницы только в том случае, если контент над разворотом является достаточно привлекательным и оправдывает усилия. Поэтому всегда показывайте результаты поиска над разворотом. Все, что находится вверху страницы, попадает в зону внимания юзеров немедленно. Не теряйте выдачу среди прочих элементов страницы, которые к поиску не имеют отношения. Пользователи ожидают увидеть товары сразу после нажатия кнопки “Поиск”, а необходимость работать колесиком мыши — это лишнее действие.
Не стоит опускать карточки товаров под рекламный баннер как на этом примере:
Карточки товаров под рекламным баннером
На следующем скриншоте результаты поиска размещены над разворотом. Пользователь сразу видит релевантные товары и заинтересован прокрутить страницу дальше.
Результаты поиска над разворотом
Макет страницы выдачи
Дайте пользователям возможность самостоятельно выбирать, как отображать результаты поиска — списком или блоком. Пример:
Можно выбирать способ отображения
Помните: при разработке макета в виде блоков важно выбрать правильный размер изображений. Изображения должны быть оптимального размера, чтобы было видно товар и при этом отображалось нормальное количество результатов, хотя бы 4 товара в одной строчке.
Если ваши картинки высокого качества и эффективно презентуют продукт, для удобства посетителей вы можете также встроить опцию детализации (лупы), позволив им приблизить любую часть изображения и детально ее рассмотреть. Это особенно важно для мобильных устройств из-за небольшого размера экрана.
Прогресс поиска
В идеале результаты поиска должны отображаться немедленно. Но если по какой-то причине это невозможно, используйте индикатор прогресса выполнения. Это даст возможность визуально информировать пользователей о том, что система работает. Например:
Индикатор прогреса поиска
Индикатор прогреса поиска
2. Расположение
Второй аспект, который нужно учитывать при разработке формы поиска на сайте — это ее расположение.
Место строки в интерфейсе имеет большое значение. Есть множество вариантов расположения окна поиска, но для улучшения пользовательского опыта — подойдут два. Самым удобным местом для юзеров будет верхний левый или верхний правый угол страницы вашего веб-сайта. Это оптимальное расположение строки продиктовано F-образным шаблоном чтения.
Исследование Eyetracking показывает, что люди читают веб-страницы и экраны телефонов по разным шаблонам, но самым популярным все же остается F-образный. Спустя 11 лет после его открытия он по-прежнему жив и здоров в современном мире. И это доказывает, что UX больше зависит от человеческого поведения, чем от технологий.
F-образный шаблон чтения
Панель поиска должна присутствовать на всех страницах вашего веб-сайта. Если пользователи не могут найти контент, который ищут — у них должна быть возможность снова воспользоваться поиском.
3.1. Функциональность строки поиска
Теперь, когда мы разобрались с дизайном и расположением, перейдем к функциональности. В конечном итоге лишь умные функции поиска позволяют пользователям находить то, что они ищут, и максимально улучшают пользовательский опыт. Маркетологам и владельцам интернет-магазинов должно быть обидно, когда на сайте есть отличный контент и популярные товары, но пользователи не могут всего этого найти. Чтобы избежать такого результата, эффективный поиск должен обладать такими функциями:
Сохранять исходный текст в поле ввода
Настройте строку так, чтобы запросы пользователей не исчезали после нажатия кнопки “Поиск”. Если пользователи не найдут то, что ищут с первой попытки, они смогут уточнить свой запрос дополнительными словами. Чтобы им было проще это сделать, оставьте первоначальный запрос видимым в поле поиска как на рисунке ниже. Тогда пользователям не придется повторно вводить его.
Исходный текст сохранён
Предлагать автоподсказки
Предложите покупателю то, что ему нужно! Функция автоподсказок экономит время пользователя. Так, во время ввода поисковой фразы отображается блок с подсказками:
- автозаполнение или продолжение запроса;
- категории товаров;
- список товаров;
- продвигаемый товар/бренд.
Моментальные автоподсказки
Они помогают ускорить процесс поиска для пользователя и направляют его к действию, которое повысит конверсию на сайте. Особенно этот функционал облегчает жизнь мобильным юзерам вашего ресурса. Кому охота лишний раз попадать в маленькие кнопки виртуальной раскладки? Но помните, что список подсказок не должен быть слишком длинным, чтобы не отвлекать внимание пользователя просмотром ненужных результатов.
Исправлять ошибки и опечатки
По статистике Multisearch 10-15% пользователей допускают ошибки в запросе, более 50% из них не уточняют поисковой запрос. Они просто покидают сайт в надежде найти нужный товар в другом месте. Поэтому важно, чтобы поиск понимал, что ищет клиент.
Автоматическое исправление ошибок
Понимать синонимы и учитывать морфологию
Чтобы пользователь увидел нужные товары, умный поиск обязан обрабатывать запросы во всех морфологических формах — род, падеж, число, склонение и часть речи. А также понимать контекст запроса и определять слова синонимы. На рисунке внизу поиск учитывает множественную форму синонима к слову мобильный телефон.
Поиск понимает синонимы
Распознавать транслитерацию
Научите строку при выполнении поиска переводить латиницу в кириллицу и наоборот. Когда поиск понимает транслитерацию, то нет разницы, каким алфавитом пользователь вводит запрос, смотрите пример ниже. Эта функция в разы сокращает количество ненайденных результатов.
Транслитерация работает
Хранить историю запросов
Сформулировать, ввести и запомнить запрос — задача не всегда простая для покупателя. При разработке поиска вы должны помнить об основном правиле юзабилити — уважайте усилия пользователей. Ваша строка должна хранить все недавние запросы юзера, чтобы предоставлять эти данные ему при следующем взаимодействии с панелью. Это не только облегчает путь клиента к покупке, но и повышает лояльность к сайту — позитивный опыт хочется повторить.
Отображается история запросов
3.2. Функциональность страницы с результатами
Рассмотрим дальше возможности для улучшения поисковой выдачи:
Предоставлять точные и актуальные результаты
Первая страница результатов — “золотая”. Именно результаты, которые посетители видят на этой странице, формируют окончательное решение посетителя: купить продукт в этом интернет-магазине или посмотреть его в другом. Все зависит от их релевантности. Пользователи очень часто судят о ценности веб-ресурса, основываясь на качестве результатов выдачи. Таким образом, важно правильно расставить приоритеты — все самые релевантные товары должны появиться на первой странице выдачи. Синоним качества поиска — его релевантность. Когда результаты выдачи соответствуют ожиданиям пользователя, значит они релевантны. Но, чтобы сделать из строки настоящий генератор дохода, одной релевантности будет недостаточно. Для этого умный поиск может влиять на порядок ранжирования результатов. То есть строка будет учитывать, какие товары показывать выше, а какие ниже, с учетом важных для Ecommerce признаков. Хороший пример релевантной выдачи на сайте доставки продуктов питания:
Как должен выглядеть поиск по сайту в интернет-магазине. Семь правил, которые необходимо учесть
Обычно при создании сайта интернет-магазина далеко не каждый владелец задумывается на тему, как будет выглядеть поиск на его сайте. А ведь этот вопрос достаточно важен! С каждым годом становится все больше и больше людей, которые вместо того, чтобы искать товар в каталоге, предпочитают забить название в поисковую строку и узнать, есть ли такой или похожий товар на у вас или нет. И если они не смогли быстро найти то, что нужно, то могут очень быстро уйти. В этой статье рассмотрим, что необходимо учесть на своем сайте, чтобы сделать поиск для пользователя максимально удобным и полезным.
Вот несколько простых правил, которые помогут улучшить поиск на вашем сайте, если конечно этого еще не сделан
1) Поисковая строка должна быть заметна пользователю. В идеале если она будет «сквозной» на всем сайте — это когда она будет отображаться на всех страницах. Начинающие предприниматели без опыта, обычно пихнут ее куда-нибудь, мол, чтобы была. Нужно понимать, что пользователь за день может просматривать десятки (если не сотни) сайтов и если он в течении нескольких секунд не нашел поисковую строку где-нибудь в «стандартных» местах сайта, то может дальше и не искать и ли вовсе закрыть сайт. Если обращали внимание, у крупных игроков рынка поисковая строка находится где-нибудь в шапке сайта или около нее. И сделано это неспроста.
2) Поиск должен искать то, что нужно. Казалось бы, очевидная вещь, но к сожалению, поиск у ряда CMS-систем или конструкторов сайтов работает мягко говоря через одно место. И находит совершенно не то, что нужно или релевантность результатов сильно нарушена. В общем, пользователю приходится еще долго ковыряться в результатах поиска, в поисках того, что ему нужно.
3) В поиске должны отсутствовать товары, которые нельзя купить. Бывает и такое, когда вводишь на сайте поисковый запрос, а в самом начале страницы (или вообще несколько первых страниц) показываются товары, которых нет в наличии. Или они вперемешку с теми, которые в наличии есть, и пользователь опять же вынужден еще долго разбираться с тем, что же ему предлагает ваш сайт. Постарайтесь скрыть подобные товары из выдачи, или хотя бы выводить их в самую последнюю очередь.
4) Вывод результатов поиска должен напоминать каталог. Это не обязательное условие, но желательное. Пользователю, привыкшему видеть ваш каталог в определенном виде, значительно проще работать с поисковой выдачей в таком же виде (если он ищет товар). Если у вас по сайту могут также искаться новости, статьи и т.д., то их лучше отделить от товара и сделать в ином дизайне, например, чуть ниже товаров. Совсем не лишним будет сделать сортировку по результатам, переключение вида (список, плитка – если у вас несколько вариантов используется), возможно вывод категорий каталога, в которых найден товар и прочие удобства.
Поиск на сайте: особенности и настройка

Получи нашу книгу «Контент-маркетинг в социальных сетях: Как засесть в голову подписчиков и влюбить их в свой бренд».
Подпишись на рассылку и получи книгу в подарок!

Поиск на сайте – это функция, сформированная внутри самого ресурса, которая предназначена для быстрого и удобного подбора интересующего контента.
Больше видео на нашем канале — изучайте интернет-маркетинг с SEMANTICA

Если ваш сайт имеет более 20 страниц, то возможность внутреннего поиска в нем должна быть предусмотрена в обязательном порядке. В настоящее время существует множество вариантов для реализации внутреннего поиска, каждый из которых обладает своими особенностями.
Рассмотрим простой пример, чтобы понять, для чего нужен поиск по сайту. Зайдите на Avito.ru, где размещаются миллионы объявлений. Максимально быстро найти искомую информацию на таком огромном ресурсе можно только воспользовавшись функцией поиска на сайте.
Признаки хорошего поиска на сайте
Существует несколько общих параметров, которые работают для каждого посетителя:
- Поиск по сайту должен быть видимым. Он должен располагаться в удобном месте на главной странице.
- Любому пользователю должно быть понятно, что на сайте есть форма поиска. Без добавления поля с опознавательными знаками и соответствующим заголовком сложно понять, что это поиск по сайту.
Что требуется от поиска на сайте
Настройка поиска по сайту предполагает реализацию нескольких функций в рамках определенного ресурса:
- Поиск с учетом морфологии. Вне зависимости от окончания, падежа и прочих особенностей русского языка, система должна искать именно то, что нужно посетителю. Один из вариантов достижения необходимого результата – приведения всех слов из запроса и фраз контента сайта к нужной форме.
- Формирование контекста поиска. Автономный выбор контекста сайта, в рамках которого функционирует поисковый алгоритм, а также определение значимости для всех таких рамок. Например, в интернет-магазине основным приоритетом формы поиска по сайту будут выступать наименования товаров. Второе приоритетное значение – подбор по свойствам продукции и т.д.
- Индексация содержимого ресурса. Процедура осуществляется только после изменения или дополнения содержимого. Поиск ведется по индексу.
- Механизм ранжирования. Ранжирование поисковых результатов – это их сортировка, которая осуществляется на основе анализа значимости собранных данных. Например, если идентичные слова содержатся в двух разных статьях, то приоритетным будет результат, где данное слово отображено в большем количестве.
В чем заключается настройка поиска на сайте
В процессе установки поиска по сайту необходимо настроить морфологический анализатор, алгоритм ранжирования, индексирования и поиска.
Принцип функционирования правильно настроенного поиска:
- Содержимое ресурса индексируется.
- Пользователь вводит запрос.
- Из запроса убираются служебные части предложения.
- Строка делится на массив слов, переведенных в базовый вариант.
- Поиск слов осуществляется в индексе.
- Результаты подлежат ранжированию. Они сортируются и направляются аудитории.
Как сделать поиск по сайту с помощью Google и Яндекс
Рассмотрим, как сделать поиск по сайту с помощью Яндекса. Он предлагает бесплатную модель интеграции поиска. Она удобная, и кроме морфологии, исправления опечаток и ошибок предоставляет возможность добавить к каждому слову перечень синонимов и специальную форму подсказок. Это с большой вероятностью поможет быстро найти искомый контент.
Настройки поиска по сайту предельно просты. Установить все параметры можно самостоятельно. Сервис имеет гибкие настройки элементов поиска и внешнего вида, что дает возможность оформить его в соответствии со стилем ресурса в необходимых цветах. Искать можно не только текст, но и картинки.
Настройка поиска Яндекс
Настройка поиска по сайту осуществляется с помощью инструмента Яндекс.Вебмастер. Необходимо зайти в поиск Яндекса и нажать «Установить поиск». После этого нужно внести все данные, требуемые системой, в том числе название сайта, электронный адрес и параметры поиска. Далее осуществляется подбор внешнего вида функции, указывается, где именно будет располагаться страница поиска по сайту. Затем проводится проверка его работы. Если все в порядке, то функция добавляется на сайт с помощью копирования кода сервиса.
Особенности и настройка поиска Google
В отличие от Яндекса, Google – платный инструмент, но спрос на него очень высокий. Оплачивая около 100 долларов США в год, владелец ресурса получает:
- Персонализированный внешний вид поиска. Можно убрать логотип сервиса и настроить свой.
- Поиск на всех языках.
- Поиск на сайте с синонимайзерами, дающий возможность мгновенно найти то, что нужно, даже если запрос был написан не так, как он отображен на ресурсе.
- Индексирование при необходимости – возможность направлять информацию поисковому роботу сразу после сохраненных изменений.
- Возможность поиска на нескольких ресурсах одновременно.
- Ведение статистики.
- Доход от рекламы.
Как сделать поиск по сайту с помощью Google? Требуется зайти в систему пользовательского поиска Google и заполнить специальную форму. Затем можно подобрать стили, шрифты, цвета для строки поиска и т.д. После завершения настроек нужно скопировать сгенерированный код в тело страницы, где будет отображаться функция.
Поиск по сайту – это обязательный инструмент любого ресурса, один из элементов лояльности пользователей к нему. Всем, кто не знает, как его сделать с помощью PHP и HTML, не имеет навыков в web-программировании, оптимальный вариант – применить скрипты от Яндекса и Google. Они максимально адаптированы под эту функцию, и реально помогают в продвижении сайта в топ выдачи.
Рассказать о статье:

Получите профессиональный взгляд со стороны на свой проект
Специалисты студии SEMANTICA проведут комплексный анализ сайта по следующему плану:
– Технический аудит.
– Оптимизация.
– Коммерческие факторы.
– Внешние факторы.
Мы не просто говорим, в чем проблемы. Мы помогаем их решить

29.01.2018 36022
Нейромаркетинг: что это такое Нейромаркетинг «собрал в себе» все способы влияния на человека, чтобы побудить его потреблять больше. Эйл Смидс в 2002 году объединил два слова: нейробиология и маркетинг. Получившийся термин описывает коммерческое использование открытий нейробиологии. С помощью изучения мозга стояла задача понять потребителя и повысить продажи. Обычный пример: если вы ходили по магазинам, то, наверно, замечали, как в одном…

11.03.2018 32190
Front-end разработчик – это программист, основная задача которого состоит в разработке пользовательского интерфейса, то есть UI дизайна. Другими словами, данный специалист отвечает за внешнюю часть веб-ресурса в браузере, с которой контактируют посетители. Именно поэтому он должен сделать интерфейс максимально удобным и интуитивно понятным, чтобы взаимодействие и процесс поиска нужного раздела или информации не занимало у человека много времени и переходов…
27.06.2018 50325
Конкурсы –– один из способов продвижения блога. С их помощью вы общаетесь с аудиторией, привлекаете в блог новых подписчиков и активизируете старых. Суть в том, что вы обещаете участникам подарок за то, что они тем или иным образом расскажут о вас другим пользователям. Этот метод раскрутки считается эффективным. Какие виды розыгрышей можно провести Существуют три механики, которые маркетологи советуют чередовать…
Поиск на сайте своими руками

Наверное, многие когда-нибудь задумывались, как сделать поиск на сайте? Безусловно, для крупных сайтов с большим количеством контента поиск является просто незаменимой вещью. В большинстве случаев пользователь, впервые посетив Ваш сайт в поисках чего-либо важного, не станет разбираться в навигационных панелях, выпадающих меню и прочих элементах навигации, а в спешке попытается найти что-нибудь похожее на поисковую строку. И если такой роскоши на сайте не окажется, либо он не справится с поисковым запросом, то посетитель просто закроет вкладку. Но статья не о значении поиска для сайта и не о психологии посетителей. Я расскажу, как реализовать небольшой алгоритм полнотекстового поиска, который, надеюсь, избавит начинающих разработчиков от головной боли.
У читателя может возникнуть вопрос: зачем писать все с нуля, если все уже давно написано? Да, у крупных поисковиков есть API, есть такие клевые проекты, как Sphinx и Apache Solr. Но у каждого из этих решений есть свои преимущества и недостатки. Пользуясь услугами поисковиков, типа Google и Яндекс, Вы получите множество плюшек, таких как мощный морфологический анализ, исправление опечаток и ошибок в запросе, распознавание неверной раскладки клавиатуры, однако без ложки дегтя тут не обойдется. Во первых, такой поиск не интегрируется в структуру сайта — он внешний, и Вы не сможете указать ему, какие данные наиболее важны, а какие не очень. Во вторых, содержимое сайта индексируется только с определенным интервалом, который зависит от выбранного поисковика, так что если на сайте что-нибудь обновится, придется дожидаться момента, когда эти изменения попадут в индекс и станут доступными в поиске. У Sphinx и Apache Solr дела с интеграцией и индексированием гораздо лучше, но не каждый хостинг позволит из запустить.
Ничто не мешает написать поисковый механизм самостоятельно. Предполагается, что сайт работает на PHP в связке с каким-нибудь сервером баз данных, например MySQL. Давайте сначала определимся, что требуется от поиска на сайте?
- Поиск с учетом языковой морфологии. Независимо от падежа, окончания и
других прелестей великого и могучего языка поиск должен находить то, что нужно
пользователю. Другими словами, «яблок», «яблока», «яблоки» — это формы одного и того
же слова «яблоко», что нужно учитывать в поисковом алгоритме. Одним из способов
достижения данной цели является приведение каждого слова поискового запроса и слов
содержимого сайта к базовой форме. - Возможность указать контекст поиска. То есть, возможность самостоятельно выбрать
контент сайта, в пределах которого будет работать поисковый алгоритм, а также определить
значимость для каждого из пределов. Например, рассмотрим интернет-магазин. Предполагается,
что поисковый запрос чаще всего будет содержать название искомой продукции, поэтому поиск по
названиям товара будет иметь наивысший приоритет. В качестве следующего приоритета можно
выбрать поиск по свойствам товаров, затем поиск по описанию. - Индексирование содержимого сайта. Представьте ситуацию: одновременно около 30 человек
выполняют поисковые запросы. Сервер принимает каждое соединение, управление потоком
передается интерпретатору PHP. При каждом запросе заново инициализируется поисковый
движок, заново перерывается содержимое сайта… Сложно сказать, сколько времени и
ресурсов потребуется, чтобы обработать все эти запросы. Именно для того, чтобы не
делать одну и ту же работу по сто раз, была придумана технология индексирования.
Индексирование выполняется только при изменении или добавлении содержимого сайта,
а поиск выполняется уже по индексу, а не по содержимому. - Механизм ранжирования. Ранжирование результатов поиска — это сортировка результатов поиска, выполняемая на основе оценки значимости найденных данных. Например, в каком-нибудь блоге выполняется поисковый запрос «космос». Данное слово содержится в двух статьях: в первой 16 раз, во второй — 5 раз. Вероятнее всего, первая статья будет иметь большее значение для инициатора поиска. Также каждой разновидности содержимого сайта при индексировании задается определенный коэффициент, который будет влиять на его позиции в поисковой выдаче.
- морфологический анализатор,
- алгоритм ранжирования,
- алгоритм индексирования,
- алгоритм поиска.
В конце статьи будет показан пример реализации поиска на примере простого интернет-магазина. Тем, кому лень все это изучать и просто нужен готовый поисковик, можно смело забирать движок из репозитория GitHub FireWind.
Принцип работы
- содержимое сайта индексируется,
- пользователь присылает запрос,
- из запроса исключаются служебные части речи,
- получившаяся строка разбивается на массив слов, переведенных в базовую форму,
- поиск каждого слова полученного массива осуществляется в индексе,
- результаты поиска ранжируются, сортируются и отдаются пользователю.
Подготовка
Задача поставлена, теперь можно перейти к делу. Я использую Linux в качестве рабочей ОС, однако постараюсь не использовать ее экзотических возможностей, чтобы любители Windows смогли «собрать» поисковый движок по аналогии. Все, что Вам нужно — это знание основ PHP и умение обращаться с MySQL. Поехали!
Наш проект будет состоять из ядра, где будут собраны все жизненно необходимые функции, а также модуля морфологического анализа и обработки текста. Для начала создадим корневую папку проекта firewind, а в ней создадим файл core.php — он и будет ядром.
$ mkdir firewind $ cd firewind $ touch core.php
Теперь вооружаемся своим любимым текстовым редактором и подготавливаем каркас:
Тут мы создали основной класс, который можно будет использовать на Ваших сайтах. На этом подготовительная часть заканчивается, пора двигаться дальше.
Морфологический анализатор
Русский язык — довольно сложная штука, которая радует своим разнообразием и шокирует иностранцев конструкциями, типа «да нет, наверное». Научить машину понимать его, да и любой другой язык, — довольно непростая задача. Наиболее успешны в этом плане поисковые компании, типа Google и Яндекс, которые постоянно улучшают свои алгоритмы и держат их в секрете. Придется нам сделать что-то свое, попроще. К счастью, колесо изобретать не придется — все уже сделано за нас. Встречайте, phpMorphy — морфологический анализатор, поддерживающий русский, английский и немецкий языки. Более подробную информацию можно получить тут, однако нас интересуют только две его возможности: лемматизация, то есть получение базовой формы слова, и получение грамматической информации о слове (род, число, падеж, часть речи и т.д.).
Нужна библиотека и словарь для нее. Все это добро можно найти тут. Библиотека находится в одноименной папке «phpmorphy», словари расположены в «phpmorphy-dictionaries». Скачиваем последние версии в корневую папку проекта и распаковываем:
# Распаковываем библиотеку $ unzip phpmorphy-0.3.7.zip $ mv phpmorphy-0.3.7 phpmorphy # Распаковываем словарь в phpmorphy/dicts $ unzip morphy-0.3.x-ru_RU-withjo-utf-8.zip -d phpmorphy/dicts/ # Удаляем исходные архивы $ rm phpmorphy-0.3.7.zip morphy-0.3.x-ru_RU-withjo-utf-8.zip
Отлично! Библиотека готова к использованию. Пришло время написать «оболочку», которая абстрагирует работу с phpMorphy. Для этого создадим еще один файл morphyus.php в корневой директории:
phpmorphy = new phpMorphy( $directory, $language, $options ); > /** * Разбивает текст на массив слов * * @param content Исходный текст для выделения слов * @param filter Активирует фильтрацию HTML-тегов и сущностей * @return Результирующий массив */ public function get_words( $content, $filter=true ) < // Фильтрация HTML-тегов и HTML-сущностей // if ( $filter ) < $content = strip_tags( $content ); $content = preg_replace( $this->regexp_entity, ' ', $content ); > // Перевод в верхний регистр // $content = mb_strtoupper( $content, 'UTF-8' ); // Замена ё на е // $content = str_ireplace( 'Ё', 'Е', $content ); // Выделение слов из контекста // preg_match_all( $this->regexp_word, $content, $words_src ); return $words_src[ 1 ]; > /** * Находит леммы слова * * @param word Исходное слово * @param Массив возможных лемм слова, либо false */ public function lemmatize( $word ) < // Получение базовой формы слова // $lemmas = $this->phpmorphy->lemmatize( $word ); return $lemmas; > > ?>
Пока реализовано только два метода. get_words разбивает текст на массив слов, фильтруя при этом HTML-теги и сущности типа » «. Метод lemmatize возвращает массив лемм слова, либо false, если таковых не нашлось.
Механизм ранжирования на уровне морфологии
Давайте остановимся на такой единице языка, как предложение. Наиболее важной частью предложения является основа в виде подлежащего и/или сказуемого. Чаще всего подлежащее выражается существительным, а сказуемое глаголом. Второстепенные члены в основном употребляются для уточнения смысла основы. В разных предложениях одни и те же части речи порой имеют совершенно разное значение, и наиболее точно оценить это значение в контексте текста сегодня может только человек. Однако программно оценить значение какого-либо слова все-таки можно, хоть и не так точно. При этом алгоритм ранжирования должен опираться на так называемый профиль текста, который определяется его автором. Профиль представляет из себя ассоциативный массив, ключами которого являются части речи, а значениями соответственно ранг (или вес) каждой из них. Пример профиля я покажу в заключении, а пока попробуем перевести эти размышления на язык PHP, добавив еще один метод к классу morphyus:
word Исходное слово * @param profile Профиль текста * @return Оценка значимости от 0 до 5 */ public function weigh( $word, $profile=false ) < // Попытка определения части речи // $partsOfSpeech = $this->phpmorphy->getPartOfSpeech( $word ); // Профиль по умолчанию // if ( !$profile ) < $profile = [ // Служебные части речи // 'ПРЕДЛ' =>0, 'СОЮЗ' => 0, 'МЕЖД' => 0, 'ВВОДН' => 0, 'ЧАСТ' => 0, 'МС' => 0, // Наиболее значимые части речи // 'С' => 5, 'Г' => 5, 'П' => 3, 'Н' => 3, // Остальные части речи // 'DEFAULT' => 1 ]; > // Если не удалось определить возможные части речи // if ( !$partsOfSpeech ) < return $profile[ 'DEFAULT' ]; >// Определение ранга // for ( $i = 0; $i < count( $partsOfSpeech ); $i++ ) < if ( isset( $profile[ $partsOfSpeech[ $i ] ] ) ) < $range[] = $profile[ $partsOfSpeech[ $i ] ]; >else < $range[] = $profile[ 'DEFAULT' ]; >> return max( $range ); > > ?>
Индексирование содержимого сайта

Как уже говорилось выше, индексирование заметно ускоряет выполнение поискового запроса, так как поисковому движку не нужно обрабатывать контент каждый раз заново — поиск выполняется по индексу. Но что же все-таки происходит при индексировании? Если по порядку, то:
- Сначала из текста формируется массив слов, и делается это с помощью метода get_words.
- Согласно профилю, из текста отбрасываются незначимые части речи.
- Значимые оцениваются по пятибальной шкале, с помощью метода weigh.
- Для каждого сова выполняется поиск лемм, иначе говоря базовых форм.
- Рассчитывается количество повторений каждого слова и суммарный ранг.
- Все данные записываются в объект и в виде JSON записываются в базу данных.
В результате получается объект следующего формата:
< "range" : "", "words" : [ // Одно из слов // < "source" : "", "range" : "", "count" : "", "weight" : "", "basic" : [ // Варианты лемм слова // ] > ] >
Пишем инициализатор и первый метод ядра поискового движка:
morphyus = new morphyus; > /** * Выполняет индексирование текста * * @param content Текст для индексирования * @param [range] Коэффициент значимости индексируемых данных * @return Результат индексирования */ public function make_index( $content, $range=1 ) < $index = new stdClass; $index->range = $range; $index->words = []; // Выделение слов из текста // $words = $this->morphyus->get_words( $content ); foreach ( $words as $word ) < // Оценка значимости слова // $weight = $this->morphyus->weigh( $word ); if ( $weight > 0 ) < // Количество слов в индексе // $length = count( $index->words ); // Проверка существования исходного слова в индексе // for ( $i = 0; $i < $length; $i++ ) < if ( $index->words[ $i ]->source === $word ) < // Исходное слово уже есть в индексе // $index->words[ $i ]->count++; $index->words[ $i ]->range = $range * $index->words[ $i ]->count * $index->words[ $i ]->weight; // Обработка следующего слова // continue 2; > > // Если исходного слова еще нет в индексе // $lemma = $this->morphyus->lemmatize( $word ); if ( $lemma ) < // Проверка наличия лемм в индексе // for ( $i = 0; $i < $length; $i++ ) < // Если у сравниваемого слова есть леммы // if ( $index->words[ $i ]->basic ) < $difference = count( array_diff( $lemma, $index->words[ $i ]->basic ) ); // Если сравниваемое слово имеет менее двух отличных лемм // if ( $difference === 0 ) < $index->words[ $i ]->count++; $index->words[ $i ]->range = $range * $index->words[ $i ]->count * $index->words[ $i ]->weight; // Обработка следующего слова // continue 2; > > > > // Если в индексе нет ни лемм, ни исходного слова, // // значит пора добавить его // $node = new stdClass; $node->source = $word; $node->count = 1; $node->range = $range * $weight; $node->weight = $weight; $node->basic = $lemma; $index->words[] = $node; > > return $index; > > ?>
Теперь при добавлении или изменении данных в таблицах достаточно просто вызвать данную функцию, чтобы проиндексировать их, но это не обязательно: индексирование может быть и отложенным. Первым аргументом метода make_index является исходный текст, вторым — коэффициент значимости индексируемых данных. Ранг каждого слова, кстати, расчитывается по формуле:
* * ; // В коде это выглядит так: // $index->words[ $i ]->range = $range * $index->words[ $i ]->count * $index->words[ $i ]->weight; ?>
Хранение индексированных данных
Очевидно, что индекс нужно где-нибудь хранить, да еще и привязать к исходным данным. Наиболее подходящим местом для них будет база данных. Если индексируется содержимое файлов, то можно создать отдельную таблицу в базе данных, которая будет содержать индекс название каждого файла, а для содержимого, которое уже хранится в базе, можно добавить еще одно поле типа в структуру таблиц. Такой подход позволит разделять типы содержимого при поиске, например, названия и описание статей в случае блога.
Нерешенным остался лишь вопрос формата индексированного содержимого, ведь make_index возвращает объект, и так просто в базу данных или файл его не запишешь. Можно использовать JSON и хранить его в полях типа LONGTEXT, можно BSON или CBOR, используя тип данных LONGBLOB. Два последних формата позволяют представлять данные в более компактном виде, чем первый.
Как говорится, «хозяин — барин», так-что решать, где и как все будет храниться, Вам.
Benchmark
Давайте проверим, что у нас получилось. Я взял текст своей любимой статьи «Темная материя интернета», а именно содержимое узла #content html_format и сохранил его в отдельный файл.
make_index( $source ); // Засекаем время конца // $finish_time = microtime( true ); echo "Indexing finished: $finish_time\n"; // Результаты // $total_time = $finish_time - $begin_time; echo "Total time: $total_time\n"; ?>
На моей машине с конфигурацией:
CPU: Intel Core i7-4510U @ 2.00GHz, 4M Cache
RAM: 2×4096 Mb
OS: Ubuntu 14.04.1 LTS, x64
PHP: 5.5.9-1ubuntu4.5
Индексирование заняло около секунды:
$ php benchmark.php Indexing started: 1417343592.3094 Indexing finished: 1417343593.5604 Total time: 1.2510349750519
Думаю, вполне неплохой результат.
Реализация поиска
Остался последний и самый главный метод, метод поиска. В качестве первого аргумента метод принимает индекс поискового запроса, в качестве второго — индекс содержимого, в котором выполняется поиск. В результате выполнения возвращается суммарный ранг, рассчитанный на основе ранга найденных слов, либо 0, если ничего не нашлось. Это позволит сортировать поисковую выдачу.
target Искомые данные * @param source Данные, в которых выполняется поиск * @return Суммарный ранг на основе найденных данных */ public function search( $target, $index ) < $total_range = 0; // Перебор слов запроса // foreach ( $target->words as $target_word ) < // Перебор слов индекса // foreach ( $index->words as $index_word ) < if ( $index_word->source === $target_word->source ) < $total_range += $index_word->range; > else if ( $index_word->basic && $target_word->basic ) < // Если у искомого и индексированного слов есть леммы // $index_count = count( $index_word ->basic ); $target_count = count( $target_word ->basic ); for ( $i = 0; $i < $target_count; $i++ ) < for ( $j = 0; $j < $index_count; $j++ ) < if ( $index_word->basic[ $j ] === $target_word->basic[ $i ] ) < $total_range += $index_word->range; continue 2; > > > > > > return $total_range; > > ?>
Все! Поисковый движок готов к использованию. Но есть одно но… На самом деле это не джин-волшебник, и просто закинув его на свой сайт Вы не получите ничего. Его нужно интегрировать, причем этот процесс во многом зависит от архитектуры Вашего сайта. Рассмотрим этот процесс на примере небольшого интернет магазина.
Реализация поиска на примере интернет-магазина
Допустим, информация о продаваемой продукции хранится в таблице production:
CREATE TABLE `production` ( `uid` INT NOT NULL AUTO_INCREMENT, -- Уникальный идентификатор `name` VARCHAR(45) NOT NULL, -- Название продукта `manufacturer` VARCHAR(45) NOT NULL, -- Производитель `price` INT NOT NULL, -- Стоимость продукта `keywords` TEXT NULL, -- Индекс ключевых слов PRIMARY KEY ( `uid` ) ); SHOW COLUMNS FROM `production`; +--------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+-------+ | uid | int(11) | NO | PRI | NULL | | | name | varchar(45) | NO | | NULL | | | manufacturer | varchar(45) | NO | | NULL | | | price | int(11) | NO | | NULL | | | keywords | text | YES | | NULL | | +--------------+-------------+------+-----+---------+-------+
А описание в таблице description:
CREATE TABLE `description` ( `uid` INT NOT NULL AUTO_INCREMENT, -- Уникальный идентификатор `fid` INT NOT NULL, -- Внешний ключ для привязки описания к продукту `description` LONGTEXT NOT NULL, -- Само описание `index` TEXT NULL, -- Индексированное описание PRIMARY KEY ( `uid` ) ); SHOW COLUMNS FROM `description`; +-------------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+-------+ | uid | int(11) | NO | PRI | NULL | | | fid | int(11) | NO | | NULL | | | description | longtext | NO | | NULL | | | index | text | YES | | NULL | | +-------------+----------+------+-----+---------+-------+
Поле production.keywords будет содержать индекс ключевых слов продукта, description.index будет содержать индексированное описание. И все это будут храниться в формате JSON.
Вот пример функции добавления нового продукта:
connect_error ) < die( 'Cannot connect to database.' ); >$connection->set_charset( 'UTF8' ); function add_product( $name, $manufacturer, $price, $description, $keywords ) < global $firewind, $connection; // Индексирование описания продукта // $description_index = $firewind->make_index( $description ); $description_index = json_encode( $description_index ); // Индексирование ключевых слов // $keywords_index = $firewind->make_index( $keywords, 2 ); $keywords_index = json_encode( $keywords_index ); // Подготовка запросов // $production_query = $connection->prepare( "INSERT INTO `production` ( `name`, `manufacturer`, `price`, `keywords` ) VALUES ( ?, ?, ?, ? )" ); $description_query = $connection->prepare( "INSERT INTO `description` ( `fid`, `description`, `index` ) VALUES ( LAST_INSERT_ID(), ?, ? )" ); if ( !$production_query || !$description_query ) < die( "Cannot prepare requests!\n" ); >if ( // Биндинг параметров // $production_query -> bind_param( 'ssis', $name, $manufacturer, $price, $keywords_index ) && $description_query -> bind_param( 'ss', $description, $description_index ) && // Выполнение запросов // $production_query -> execute() && $description_query -> execute() ) < // Если запросы выполнились успешно // echo( "Product successfully added!\n" ); // Завершение запросов // $production_query ->close(); $description_query -> close(); return true; > else < die( "An error occurred while executing query. \n" ); >> ?>
Здесь поисковый механизм был интегрирован в функцию добавления нового продукта магазина. А теперь обработчик поисковых запросов:
connect_error ) < die( 'Cannot connect to database.' ); >$connection->set_charset( 'UTF8' ); // Поисковый запрос // $query = isset( $_GET[ 'query' ] ) ? trim( $_GET[ 'query' ] ) : false; if ( $query ) < // Обработка поискового запроса // $query_index = $firewind->make_index( $query ); // Получение данных // $production = $connection->query(" SELECT p.`uid`, p.`name`, p.`keywords`, d.`index` FROM `production` p, `description` d WHERE p.`uid` = d.`uid` "); if ( !$production ) < die( "Cannot get production info.\n" ); >// Выполнение поиска // while ( $product = $production->fetch_assoc() ) < // Распаковка индекса // $keywords = json_decode( $product[ 'keywords' ] ); $index = json_decode( $product[ 'index' ] ); $range = $firewind->search( $query_index, $keywords ); $range += $firewind->search( $query_index, $index ); if ( $range > 0 ) < $result[ $product[ 'uid' ] ] = $range; >> // Если что-нибудь нашлось // if ( isset( $result ) ) < // Сортировка по убыванию // arsort( $result ); // Вывод результатов // $i = 1; foreach ( $result as $uid =>$range ) < printf( "#%d. Found product with id %d and range %d.\n", $i++, $uid, $range ); >> else < echo( "Sorry, no results found.\n" ); >> else < echo( "Query cannot be empty. Try again.\n" ); >?>
Данный сценарий принимает поисковый запрос в виде GET-параметра query и выполняет поиск. В результате выводятся найденные продукты магазина.
Заключение
В статье был описан один из вариантов реализации поиска для сайта. Это самая первая его версия, поэтому буду только рад узнать Ваши замечания, мнения и пожелания. Присоединяйтесь к моему проекту на Github: https://github.com/axilirator/firewind. В планах добавить туда еще кучу всяких возможностей, вроде кэширования поисковых запросов, подсказок при вводе поискового запроса и алгоритма побуквенного сравнения, который поможет бороться с опечатками.
Всем спасибо за внимание, ну и с днем информационной безопасности!
