Случайно увидел вот такую подсказку на Озоне:



Это для меня, наверное, лучший пример, как не надо делать поиск в интернет-магазине. Дело в том, что все эти советы спокойно может взять на себя железный мозг, и разгрузить тем самым мозг пользователя. Покупатель при этом даже не заметит, что что-то пошло не так, а, значит, его ничего не остановит перед покупкой. Надо отметить, что ряд ошибок этот конкретный поиск правит, но в моём случае с копипастой названия книги из оптового прайса не прокатило.

У нас самих не лучший в мире поиск, но он продаёт. Давайте покажу, что мы сделали.

Общая архитектура


До примерно 2011 года мы использовали иерархическую систему навигации, когда товар принадлежал категории, а категория всегда лежала в суперкатегории. Ну, обычное дерево. После этого перешли к навигации тегами: фактически, любая страница каталога сайта — это всегда результат поиска. Говоря чуть шире, сама категория содержит в себе данные о том, какой товар в неё отбирать. То есть, в идеале, данные сами диктуют нашим роботам то, как их читать и что с ними делать. Эта парадигма нужна была для ряда следующих шагов, но пока остановимся на поиске.

Итак, любая страница сайта суть результат поиска. «Все товары» — это поиск без условий. «Детские» — это поиск по возрасту или тегу «Детская». «Мафия» — это подкатегория поиска по всем играм серии.

Некоторые запросы имеют статический адрес — он появляется, когда мы решаем прописать их в навигации. Ряд запросов также имеют статический адрес-алиас, но они не показываются в навигации — они нужны для поддержания правильной с точки зрения SEO структуры.

С устройством кэша, конечно, нахлебались, но это того стоило.

Обработка ошибок ввода в поиске


Пользователь вводит поисковый запрос. Если товаров в нём нет, генерируется состояние «пользователь ошибся», и дальше проверяются следующие тезисы:

1. Опечатки
У каждого товара есть набор ассоциативных ключей, которые с ним связаны. Это название, иногда производитель, разные варианты названия, оригинальное название (на языке производителя), варианты транскрибирования. Первый подход был — переписать известные опечатки и поставить их как скрытые (для отображения) алиасы названия. Мы создали такую базу неверных названий и занесли в неё всё, что пользователи хотели, но не могли найти. Подход был не самый правильный, но тогда было быстрее решить работой контент-менеджера, нежели разработкой. Позже приехал апдейт, который просто строил расстояние Дамарау-Левенштейна до ближайшего товара и предполагал, оно это или нет. Так мы полностью решили проблему даже очень жестоких опечаток.

2. Не та раскладка
К поиску просто добавляется запрос с инвертированной раскладкой. Главное — пройтись потом и фильтром опечаток тоже. С некоторых пор мы поддерживаем и транслит для людей без русской клавиатуры.

3. Неверное название товара
Многие товары ищут так, что фильтр опечаток не поможет. Если, например, «Активити» — «Активия» будет хорошо разобрано предыдущими фильтрами, то вот по запросу «Эрудит» некоторые пользовали всерьёз ожидают найти «Скрабл». Равно как и Дженгу по запросу «башня». Решается это, опять же, созданием синонимов к каждой игре, включающих наиболее распространённые ошибки запоминания названий товаров. Буквально на днях журналисты с телевидения подарили новый синоним нашему любимому «Шакалу» — теперь он ищется и по запросу «Койот».


Подсказки не перестают показываться даже при заведомо неверном варианте

4. Неверный порядок слов
Нам, в целом, на него плевать, логика обработки не меняется. Но есть люди, которые пользуются подсказками, поэтому мы выводим в список подсказок не только то, что начинается на указанное слово, но и то, что соответствует синонимам и составным частям в любом порядке. Например, если начать набирать «дет...», то в подсказках будет примерно так:


За рулём-5 — тоже детская


Ближе к пользователям. Дамерау с Левенштейном не знают, но Чебурашка — друг крокодила Гены. Это знает наша база данных синонимов товаров.

Повышаем удобство пользователя


Вернёмся на шаг назад. Пользователь вводит запрос. Возможные результаты:

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


Фильтр синонимов используется до проверки ошибок — по запросу «эрудит» находится «Скрабл»

Ровно один результат поиска
В этом случае мы научились у Википедии — нужно сразу перебрасывать на страницу результата, то есть на карточку товара. Поиск у нас прямо в шапке сайта, на видном месте, никуда не девается, то есть, если товар не тот — пользователь продолжит. А вот если тот (что куда, куда более вероятно), у него не будет пустой страницы, где единственно возможное действие — просто кликнуть по единственному же результату поиска.

Ничего не нашлось, но после фильтров есть один результат
Здесь нужно показать страницу поиска с объяснением того, как мы исправили запрос, чтобы найти нужный товар. То же самое делается, если товаров находится много, но именно здесь важно не перебросить сразу на «странный» результат.



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

Товар нашёлся, но его нет в наличии
Это уже не задача поиска. Если товар нашёлся — мы отправляем на него. Если это, например, старая версия игры, снятая с производства, либо какое-то издание, которого временно нет, может показываться специальный блок с объяснением, почему не нужно рассчитывать на эту позицию, например: «Товар снят с производства в 2011 году». И рядом будут либо новые издания, либо похожие товары, которые берутся уже из базы связанных товаров или матрицы парных товаров, но не из поиска.

Резюме


Интересно, но у нас нет полнотекстового поиска по описанию товара — такая задача просто не стоит, и даже немного путает пользователя. При желании это можно легко сделать изменением одного параметра в запросе, но мы пока этого не делаем. Потому что 99% наших запросов — это именно названия или что-то похожее на них.

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

Одна из известных проблем — форма тонкого поиска по времени партии, жанру игры и так далее находится там, где обычно бывает навигация. Некоторые её там не замечают и говорят, что поиска по наличию в конкретных магазинах у нас нет. Он есть, просто сныкался. В следующем крупном релизе мы эту форму хотим вынести прямо в страницу каталога на место первых товаров.

Из фич — у нас появилось развлечение «найди свою игру» — люди вводят фамилию, а поиск исправляет в ней пять-шесть «опечаток» и подсказывает, что ближе всего к ней.