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