В современной электронной коммерции автозапчастей поиск по номеру части (Part Number Search) является «сердцем» любого интернет-магазина или агрегатора. В отличие от обычного розничного товара, где достаточно названия и категории, автозапчасть однозначно идентифицируется только по её артикулу. Однако, как показывает практика крупных игроков рынка (в частности, платформа ABCP.ru, накалавшая опыт с 2015 года), реализация качественного поиска — задача нетривиальная, полная подводных камней.
Почему поиск по артикулу — это сложно?
Многие разработчики, не погруженные в автозапчастостроение, недооценивают сложность. На первый взгляд — простое совпадение строки. На деле — работа с «грязными» данными, множеством стандартов нумерации и бизнес-логикой заменяемости.
Основные вызовы:
- Разнообразие форматов нумерации: У каждого производителя (OEM) свой стандарт. VAG использует формат
6R0615301, Brembo —09.7011;11, Febi,14404, Zimmermann —100 1233 20. Пробелы, точки, дефисы, префиксы бренда — всё это делает прямое сравнение строк бесполезным. - Кроссы (Cross-references) и аналоги: Часто оригинальной детали (OEM) нет в наличии или она слишком дорога. Покупатель ищет заменитель (aftermarket). База кроссов — это отдельный массив данных, который должен быть актуален и полон. Отсутствие кроссов = потеря продаж.
- Альтернативные и короткие номера: Один и тот же товар может иметь «длинный» заводской номер, «короткий» складской номер поставщика, штрихкод EAN-13 и внутренний артикул магазина. Поиск должен находить по любому из них.
- Масштаб данных: Прайс-листы содержат от 5 000 до 600 000+ позиций. Алгоритм, отлично работающий на 5к записях, может «умереть» по памяти или времени отклика на 600к.
- Частая обновляемость: Каталоги обновляются еженедельно/ежедневно. Необходима архитектура, позволяющая переиндексировать данные без простоя поиска.
Архитектурный подход: API-first (Опыт ABCP.ru)
Команда ABCP.ru (платформа для создания магазинов автозапчастей) пришла к выводу, что лучше вынести сложность поиска в отдельный микросервис, доступный через REST API. Это позволяет:
- Разработчикам фронтенда/мобильных приложений не заботиться о логике нормализации номеров.
- Централизованно обновлять базу кроссов и каталогов для всех клиентов сразу.
- Масштабировать поисковый кластер независимо от веб-серверов магазинов.
Пример запроса к API поиска (упрощенно):
GET https://api.demo.abcp.ru/search/articles/?userlogin=username&article=6R0615301 Пример JSON-ответа (структура кроссов для тормозного диска VAG 6R0615301):
{
"original": {
"brand": "VAG",
"number": "6R0615301"
},
"crosses": [
{
"brand": "Brembo",
"number": "09.7011.11",
"numberFix": "09701111"
},
{
"brand": "Febi",
"number": "14404",
"numberFix": "14404"
},
{
"brand": "Jurid",
"number": "562040J",
"numberFix": "562040J"
},
{
"brand": "Zimmermann",
"number": "100 1233 20",
"numberFix": "100123320"
}
// ... другие бренды
]} Ключевое поле: numberFix — это нормализованный (очищенный) номер. Именно по нему идет реальный поиск в индексе, отбрасывая все спецсимволы, пробелы и регистр.
Ключевые этапы реализации качественного поиска
Этап 1: Нормализация (Cleansing) — фундамент всего
Перед индексацией и перед поиском любой входящий номер (и из базы, и из запроса пользователя) должен проходить через функцию нормализации:
- Приведение к верхнему регистру.
- Удаление всех неалфавитно-цифровых символов (пробелы, точки, дефисы, слеши, скобки).
- Обработка префиксов брендов (например, удаление «VAG» из номера, если он передан вместе с брендом отдельно).
- Результат:
09.7011.11→09701111;100 1233 20→100123320;
Совет: Храните в БД оба варианта: `number` (для отображения пользователю) и `numberFix` (для поиска/джойнов).
Этап 2: Работа с кросс-ссылками (Cross-references)
База кроссов — это граф, где вершины — это артикулы (Brand + NumberFix), а ребра — отношение «заменяет/аналог».
- Прямые кроссы: OEM → Aftermarket.
- Обратные кроссы: Aftermarket → OEM (важно для поиска оригинала по номеру аналога).
- Транзитивность: Если А заменяет Б, а Б заменяет В, то А заменяет В? Осторожно! В автозапчастях транзитивность часто неверна (разные модификации). Требуется экспертная проверка или флаг «проверенный кросс».
Этап 3: Индексация и поисковый движок
Для объемов 100к+ SKU стандартные `LIKE ‘%query%’` в PostgreSQL/MySQL не подходят — полный скан таблицы убьет производительность.
Рекомендуемый стек (2026 год):
- Elasticsearch / OpenSearch / Meilisearch / Typesense: Полнотекстовый поиск с поддержкой нечеткого совпадения (fuzzy search) для опечаток пользователя.
- Токенизация: Используйте `keyword` токенизатор для точного совпадения `numberFix` и `ngram`/`edge_ngram` для автодополнения (подсказок при вводе).
- Шардирование: По брендам или по первым символам `numberFix` для горизонтального масштабирования.
Этап 4: Обработка EAN-13 и штрихкодов
Многие склады и сервисы (например, Wildberries, Ozon, 1С) работают со штрихкодами. В индекс поиска обязательно нужно добавить поле `ean13` (если есть) и сделать его поисковым с тем же весом, что и `numberFix`.
Типичные ошибки («Грабли», на которые наступили за 10 лет)
Основываясь на опыте команды ABCP.ru, можно выделить топ ошибок, которых стоит избегать:
| Ошибка | Последствие | Решение |
|---|---|---|
| Поиск только по точному совпадению строки (без нормализации) | Пользователь вводит «09.7011.11», в базе «09701111» — ничего не найдено. | Всегда нормализуйте запрос и данные в `numberFix`. |
| Игнорирование коротких номеров / внутренних артикулов поставщика | Потеря заказов от B2B-клиентов, знающих только свой складской код. | Добавляйте все известные идентификаторы (Supplier SKU, EAN, OEM, Short) в поисковый индекс как синонимы. |
| Отсутствие нечеткого поиска (Fuzzy Search) | Опечатки: «6R0615301» vs «6R061530I» (буква I вместо 1) — 0 результатов. | Настройте Levenshtein distance (1-) в Elasticsearch/Meilisearch для поля номера. |
| Обновление индекса «в лоб» (Drop & Recreate) на больших объемах | Простой поиска на 10-30 минут при переиндексации 600к товаров. | Используйте алиасы (aliases) и переиндексацию в новый индекс с атомарным переключением алиаса (Zero-downtime reindex). |
| Хранение кроссов только в одну сторону (OEM -> Analog) | Нельзя найти оригинал, если клиент ввел номер аналога. | Строительство двунаправленного графа кроссов. |
Современные тренды 2026 года: LLM и Векторный поиск
К 2026 году классический точечный поиск по `numberFix` остается базой, но появляются новые слои:
- Гибридный поиск (Hybrid Search): Комбинация BM25 (ключевые слова/номера) + Vector Search (эмбеддинги описаний, применимостей к авто, названий товаров). Позволяет находить деталь по запросу «тормозные колодки передние на فولксваген гольф 7», даже если пользователь не знает номер.
- LLM-агенты для парсинга прайсов: Использование больших языковых моделей для интеллектуального извлечения `brand`, `number`, `numberFix`, `ean`, `price` из неструктурированных Excel/PDF прайс-листов поставщиков без написания десятков парсеров под каждый формат.
- Валидация кроссов через LLM: Автоматическая проверка транзитивности кроссов по техническим характеристикам (вес, габариты, материал) из каталогов TecDoc/Autodata для отсечения ложных аналогов.
Чек-лист для разработчика: MVP поиска по номеру
- [ ] Создана таблица/индекс с полями: `id`, `brand`, `number_raw`, `number_fix`, `ean13`, `supplier_sku`, `price`, `stock`.
- [ ] Реализована детерминированная функция `normalize(article_string) -> string` (UpperCase + Regex Remove Non-Alnum).
- [ ] Все входящие данные (прайсы, каталоги) проходят нормализацию при импорте, заполняя `number_fix`.
- [ ] Настроен поисковый движок (Meilisearch/Typesense/Elasticsearch) с индексацией по `number_fix`, `ean13`, `supplier_sku` (Exact Match + Prefix Search для автодополнения).
- [ ] Подключена база кроссов (своя или по API, напр. ABCP, TecDoc) с нормализацией номеров кроссов.
- [ ] API поиска возвращает: Оригинал (если введен аналог), Аналоги (если введен оригинал), Цены/Остатки по всем найденным `number_fix`.
- [ ] Реализовано кэширование популярных запросов (Redis).
- [ ] Настроен мониторинг: % запросов «ничего не найдено», латентность p95/p99, частота обновления индекса.
Поиск по номеру части, это не просто `SELECT * FROM parts WHERE article = ?`. Это сложная инженерная система, включающая нормализацию данных, управление графом кросс-ссылок, высокопроизводительную полнотекстовую индексацию и устойчивую архитектуру обновления.
Использование специализированных API (как у ABCP.ru или TecDoc) на старте позволяет сэкономить месяцы разработки и сразу получить качественную базу кроссов. В перспективе — переход на гибридный векторно-ключевой поиск и автоматизацию качества данных через ИИ.
Статья подготовлена на основе открытых материалов (Habr, ABCP.ru) и лучших практик индустрии автозапчастей на 2026 год.