# Фасетный поиск: проблемы и особенности реализации
Фасетный поиск позволяет покупателю ориентироваться в больших каталогах путем последовательного сужения поиска с помощью фильтров-фасетов.
Работает это по принципу продавца-консультанта: он задает наводящие вопросы и приводит клиента в нужный отдел.
Какой цвет? Какой размер? В результате покупатель попадает к товарам, максимально соответствующим его запросам.
В зависимости от технической реализации, трудности могут начаться уже после первого фильтра. Фасет - это конкретная характеристика товара: цвет, размер и многое другое.
Например, покупатель ищет красные ботинки. После запроса API возвращает подходящие товары и доступные для них фильтры:
- Получены фильтры: Размер:
{ name: 35, count:19 }, { name: 36, count: 12 }, { name: 37, count: 8 }, Материал:{ name: кожа, count: 15 }, { name: резина, count: 4 } - Пользователь выбирает: Размер: 35
- На сервер уходит запрос с выбранным фильтром
- Сервер находит товары с этим фильтром и возвращает только те фасеты, которые есть у этих товаров
- Предположим, что из девятнадцати моделей обуви тридцать пятого размера нет ни одной с материалом резина. Теперь наши фильтры выглядят так: Размер:
{ name: 35, count:19 }, Материал:{ name: кожа, count: 15 } - Интерфейс перерисовывается и остаются только эти активные фильтры
Такая ситуация возможна, если фильтрация и отрисовка интерфейса реализованы динамически.
То есть после каждого запроса пользователь видит новый набор фильтров из тех, что имеются у постоянно сужающегося перечня товаров.
Такой подход, при всей его простоте реализации и «чистоте» интерфейса, имеет серьезный недостаток.
Актуальный пример
Представьте, что покупатель ищет товар с определёнными характеристиками. Но он применил фильтр по локации и указал, например, Москву.
Конкретно в Москве такого товара нет, но он есть в наличии в других локациях.
Покупатель может счесть, что такого товара у вас нет в принципе, поскольку из-за уменьшения количества фильтров в интерфейсе можно забыть, что поиск был ограничен конкретной локацией.
# Как избежать потери контекста в фасетном поиске
Фиксированная структура фасетов позволяет избежать проблем, описанных выше. Главное условие - сохранить изначальную структуру фасетов и обеспечить её обновление вместе с новыми запросами.
Рассмотрим как это может выглядеть:
- Получены фильтры: Размер:
{ name: 35, count:19 }, { name: 36, count: 12 }, { name: 37, count: 8 }, Материал:{ name: кожа, count: 15 }, { name: резина, count: 4 } - Структура фасетов сохраняется на стороне клиента (кэш, Session Storage, менеджер состояния приложения)
- Пользователь выбирает: Размер: 35
- На сервер уходит запрос с выбранным фильтром
- Сервер находит товары с этим фильтром и возвращает только те фасеты, которые есть у этих товаров
- Клиентская логика не заменяет старые фасеты новыми. Вместо этого обновляется сохраненная копия на основе нового ответа. Например, новая структура фильтров может выглядеть так: Размер:
{ name: 35, count:19 }, { name: 36, count: 0 }, { name: 37, count: 0 }, Материал:{ name: кожа, count: 15 }, { name: резина, count: 0 }. Используется обозначение количества товаров для каждого фасета - Интерфейс отображает полный список фасетов с указанием количества найденных совпадений
Главные преимущества такого подхода: сохранение контекста — наглядно видно, какие свойства товара были найдены поиском, а какие нет; предсказуемость — изменения в интерфейсе понятны и логичны.
Ключевые требования для реализации такого подхода:
- Сохранение структуры фасетов на стороне клиента.
- Сохранённые фасеты должны обновляться при новых запросах, а не заменяться.
Варианты хранения структуры фасетов
Для хранения можно использовать кэш — это обеспечит максимальное быстродействие, но данные пропадут при перезагрузке страницы.
Другой вариант — Session Storage сохранит данные до закрытия вкладки, но нужно учитывать ограничения объема памяти.
Реализация хранения через менеджер состояния приложения потребует дополнительных ресурсов разработки.
Выбор зависит от ваших потребностей. Но в любом случае фасетный поиск без потери контекста можно реализовать только с условием выполнения названых требований на стороне клиента.