Поиск и каталог для интернет-магазина автозапчастей: сайт находит деталь по артикулу, даже если его ввели с пробелами, дефисом или с опечаткой в названии, предлагает аналоги и показывает применимость к автомобилю. Сделал Евгений Росляков. Сайты и интернет-магазины он разрабатывает с 2016 года, живёт в Москве, берёт заказы и удалённо. Работает самозанятым, заключает договор, юридическим лицам передаёт закрывающие документы.
В магазине сотни тысяч позиций и десятки тысяч кроссов, то есть соответствий между артикулами разных производителей. Старый поиск искал точное совпадение в SQL-базе и отвечал по несколько секунд. Покупатели пишут «BK 1550», «bk-1550» или «BK1550», а находилось только одно из трёх. Аналоги не показывались совсем, и человек уходил к конкурентам.
Ещё одна беда: у тормозной колодки, масляного фильтра и лампочки нет общих характеристик. В старой базе это была одна таблица с сотней столбцов, из которых у каждой запчасти заполнены пять.
Задача — создание сайта, где запчасть находят быстро и с первого раза, а страницы товаров не ждут ответа поставщиков.
Поиск перенёс на Elasticsearch. Основная работа была с артикулами: при индексации они нормализуются, то есть убираются пробелы, дефисы и точки, выравнивается регистр. Запрос проходит ту же обработку, поэтому «BK 1550» и «bk-1550» находят один товар. Опечатки прощаются только в названиях, а для артикулов нечёткий поиск выключен: соседние артикулы обозначают разные детали, и «почти тот же» тут опасен. Для названий добавил словарь синонимов: «колодки» и «тормозные накладки», «фара» и «блок-фара».
Аналоги хранятся как связи между артикулами. Если нужной детали нет в наличии, в выдаче сразу идут замены с пометкой «аналог». Подсказки в строке поиска работают по началу артикула и названия.
Карточки товаров и применимость к автомобилям лежат в NoSQL-хранилище MongoDB. Для такого каталога оно удобнее таблиц: у каждой группы запчастей свои поля, а документ хранит ровно те характеристики, которые у неё есть. Применимость, то есть список марок, моделей и годов, вложена в карточку и подгружается вместе с ней. В Elasticsearch данные попадают из MongoDB по расписанию и при правке карточки.
Redis стоит между сайтом и поставщиками. Цены и остатки приходят прайсами и по API, я складываю их в кэш с коротким временем жизни. Страница товара отдаёт данные из памяти и не ждёт внешние системы. В Redis же лежит корзина покупателя, поэтому она не пропадает при перезагрузке страницы. При оформлении заказа остаток проверяется у поставщика ещё раз.
Для Ecommerce такая связка работает просто: Elasticsearch ищет, MongoDB описывает, Redis хранит то, что быстро меняется.
Поиск по артикулу отвечает почти мгновенно и находит товар при любом написании. Аналоги показываются сразу, поэтому покупатель не уходит с пустой выдачей. Цены и остатки на странице свежие, корзина сохраняется между визитами. Каталог теперь легко пополнять новыми группами товаров: для них не нужно переделывать структуру.
Менеджеры заметили и другое: стало меньше звонков вида «посмотрите, есть ли такая колодка». Покупатель сам видит применимость и замены, и вопросы к менеджеру задают уже по делу.
Есть ограничения. Качество аналогов зависит от базы кроссов: где поставщик не прислал соответствие, замены не будет, и такие места магазин дополняет вручную. Остаток из кэша может устареть на то время, пока он хранится, поэтому окончательная проверка стоит на оформлении заказа. Если поставщик в этот момент недоступен, покупателю показывается «уточняется».
Дальше магазин хочет подключить поиск по VIN. Структура карточек и применимости к этому готова.
Пришлите мне на freelance.ru сообщение: сколько у вас позиций и откуда приходят цены и остатки. Отвечу, как бы я построил поиск именно под такой каталог.